1 use std::env; 2 use std::fs; 3 use std::iter; 4 use std::path::{self, Path}; 5 6 /* 7 #[doc(hidden)] 8 #[macro_export] 9 macro_rules! count { 10 () => { proc_macro_call_0!() }; 11 (!) => { proc_macro_call_1!() }; 12 (!!) => { proc_macro_call_2!() }; 13 ... 14 } 15 */ 16 main()17fn main() { 18 // Tell Cargo not to rerun on src/lib.rs changes. 19 println!("cargo:rerun-if-changed=build.rs"); 20 21 let mut content = String::new(); 22 content += "#[doc(hidden)]\n"; 23 content += "#[macro_export]\n"; 24 content += "macro_rules! count {\n"; 25 for i in 0..=64 { 26 let bangs = iter::repeat("!").take(i).collect::<String>(); 27 content += &format!(" ({}) => {{ proc_macro_call_{}!() }};\n", bangs, i); 28 } 29 content += " ($(!)+) => {\n"; 30 content += " compile_error! {\n"; 31 content += " \"this macro does not support >64 nested macro invocations\"\n"; 32 content += " }\n"; 33 content += " };\n"; 34 content += "}\n"; 35 36 let content = content.as_bytes(); 37 let out_dir = env::var("OUT_DIR").unwrap(); 38 let ref dest_path = Path::new(&out_dir).join("count.rs"); 39 40 // Avoid bumping filetime if content is up to date. Possibly related to 41 // https://github.com/dtolnay/proc-macro-hack/issues/56 ...? 42 if fs::read(dest_path) 43 .map(|existing| existing != content) 44 .unwrap_or(true) 45 { 46 fs::write(dest_path, content).unwrap(); 47 } 48 49 println!("cargo:rustc-env=PATH_SEPARATOR={}", path::MAIN_SEPARATOR); 50 } 51