haste_macro_loads/
lib.rs

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        // call site location.
16        let span = proc_macro::Span::call_site();
17        // get the path from the call site.
18        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}