proc_macro_crate_name_test_macros/
lib.rs1use proc_macro::TokenStream;
2use std::path::PathBuf;
3use walkdir::WalkDir;
4
5fn proc_macro_caller_crate_root() -> PathBuf {
6 let crate_name =
7 std::env::var("CARGO_PKG_NAME").expect("failed to read ENV var `CARGO_PKG_NAME`!");
8 let current_dir = std::env::current_dir().expect("failed to unwrap env::current_dir()!");
9 let search_entry = format!("name=\"{crate_name}\"");
10 for entry in WalkDir::new(¤t_dir)
11 .into_iter()
12 .filter_entry(|e| !e.file_name().eq_ignore_ascii_case("target"))
13 {
14 let Ok(entry) = entry else { continue };
15 if !entry.file_type().is_file() {
16 continue;
17 }
18 let Some(file_name) = entry.path().file_name() else { continue };
19 if !file_name.eq_ignore_ascii_case("Cargo.toml") {
20 continue;
21 }
22 let Ok(cargo_toml) = std::fs::read_to_string(&entry.path()) else {
23 continue
24 };
25 if cargo_toml
26 .chars()
27 .filter(|&c| !c.is_whitespace())
28 .collect::<String>()
29 .contains(search_entry.as_str())
30 {
31 return entry.path().parent().unwrap().to_path_buf();
32 }
33 }
34 current_dir
35}
36
37#[proc_macro]
38pub fn my_macro(_tokens: TokenStream) -> TokenStream {
39 let crate_name = std::env::var("CARGO_PKG_NAME").unwrap();
40 let working_dir = std::env::current_dir().unwrap().display().to_string();
41 let root = proc_macro_caller_crate_root()
42 .as_path()
43 .to_str()
44 .unwrap()
45 .to_string();
46 println!("CRATE_NAME: {}", crate_name);
47 println!("WORKING_DIR: {}", working_dir);
48 println!("CRATE_ROOT: {}", root);
49 format!("(\"{crate_name}\", \"{working_dir}\", \"{root}\")")
50 .parse()
51 .unwrap()
52}