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]
9pub fn load_artifacts(input: TokenStream) -> TokenStream {
10 let mut token_include_paths = Vec::new();
11 for token_tree in input.into_iter() {
12 let literal_stream: TokenStream = token_tree.into();
13 let literal = parse_macro_input!(literal_stream as Lit);
14
15 let span = proc_macro::Span::call_site();
17 let source_file = span.local_file().unwrap();
19 let source_file_path = source_file.as_path();
20 let parent_path = source_file_path.parent().unwrap();
21
22 match literal {
23 Lit::Str(lit_str) => {
24 let directory = lit_str.value();
25 let path = Path::new(&directory);
26
27 let location = parent_path.join(path);
28
29 for entry in WalkDir::new(location) {
30 let path = entry.as_ref().unwrap().path();
31 if !path.is_dir() && path.extension().map_or(false, |ext| ext == "json") {
32 let entry_path = path.to_str().unwrap();
33 token_include_paths.push(entry_path.replace(
34 (parent_path.to_str().unwrap().to_string() + "/").as_str(),
35 "",
36 ));
37 }
38 }
39 }
40 _ => {
41 panic!("Invalid literal for macro.")
42 }
43 }
44 }
45
46 let ret = quote! {
47 &[ #(include_str!(#token_include_paths)),* ]
48 };
49
50 ret.into()
51}