1use std::path::Path;
2
3use proc_macro::TokenStream;
4use quote::quote;
5use syn::{Lit, parse_macro_input};
6use walkdir::WalkDir;
7
8#[proc_macro]
21pub fn load_artifacts(input: TokenStream) -> TokenStream {
22 let mut token_include_paths = Vec::new();
23 for token_tree in input {
24 let literal_stream: TokenStream = token_tree.into();
25 let literal = parse_macro_input!(literal_stream as Lit);
26
27 let span = proc_macro::Span::call_site();
29 let source_file = span.local_file().unwrap();
31 let source_file_path = source_file.as_path();
32 let parent_path = source_file_path.parent().unwrap();
33
34 match literal {
35 Lit::Str(lit_str) => {
36 let directory = lit_str.value();
37 let path = Path::new(&directory);
38
39 let location = parent_path.join(path);
40
41 for entry in WalkDir::new(location) {
42 let path = entry.as_ref().unwrap().path();
43 if !path.is_dir() && path.extension().is_some_and(|ext| ext == "json") {
44 let entry_path = path.to_str().unwrap();
45 token_include_paths.push(entry_path.replace(
46 (parent_path.to_str().unwrap().to_string() + "/").as_str(),
47 "",
48 ));
49 }
50 }
51 }
52 _ => {
53 panic!("Invalid literal for macro.")
54 }
55 }
56 }
57
58 quote! {
59 &[ #(include_str!(#token_include_paths)),* ]
60 }
61 .into()
62}