• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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()17 fn 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