mirams_proc_macros/
lib.rs

1extern crate proc_macro;
2
3use proc_macro::TokenStream;
4use quote::quote;
5use std::fs;
6use std::path::Path;
7use std::path::PathBuf;
8use syn::{parse_macro_input, LitStr};
9
10fn get_crate_dir() -> PathBuf {
11    PathBuf::from(std::env::var_os("CARGO_MANIFEST_DIR").unwrap())
12}
13
14fn list_dir_recursively(base_path: &Path) -> Vec<String> {
15    let base_path = get_crate_dir().join(base_path);
16    let mut module_list = Vec::new();
17    for entry in fs::read_dir(base_path).expect("Failed to read directory") {
18        let entry = entry.expect("Failed to read entry");
19        let path = entry.path();
20        if path.is_dir() {
21            module_list.extend(list_dir_recursively(&path));
22        } else {
23            let name = path.to_str().expect("Failed to convert OsString to String").to_string();
24            module_list.push(name);
25        }
26    }
27    module_list
28}
29
30/// Generate a recursive list of all files in a directory
31/// ```
32/// use mirams_proc_macros::generate_recursive_dir_list;
33/// 
34/// const FILES: &'static [&'static str] = &generate_recursive_dir_list!(".");
35/// println!("{:?}", FILES);
36/// ```
37#[proc_macro]
38pub fn generate_recursive_dir_list(input: TokenStream) -> TokenStream {
39    // Parse the input as a string literal representing the base directory path
40    let base_path = parse_macro_input!(input as LitStr).value();
41
42    // Generate the file list recursively
43    let path_list = list_dir_recursively(base_path.as_ref());
44
45    // Generate the static array of string slices
46    let path_array = quote! {
47        [
48            #(#path_list),*
49        ]
50    };
51
52    // Return the output as a TokenStream
53    path_array.into()
54}
55
56/// Generate a recursive list of pairs of the paths and the file contents
57/// for all files in a directory, returning an array of `(&str, &[u8])` tuples
58/// 
59/// ```
60/// use mirams_proc_macros::generate_recursive_dir_content_list;
61/// 
62/// const FILES: &'static [(&'static str, &'static [u8])] = &generate_recursive_dir_content_list!(".");
63/// println!("{:?}", FILES);
64/// ```
65#[proc_macro]
66pub fn generate_recursive_dir_content_list(input: TokenStream) -> TokenStream {
67    // Parse the input as a string literal representing the base directory path
68    let base_path = parse_macro_input!(input as LitStr).value();
69
70    // Generate the file list recursively
71    let path_list = list_dir_recursively(base_path.as_ref());
72
73    // Generate the static array of pairs of path strings and file contents
74    let content_array = quote! {
75        [
76            #(
77                (
78                    #path_list,
79                    std::include_bytes!(#path_list) as &[u8]
80                )
81            ),*
82        ]
83    };
84
85    // Return the output as a TokenStream
86    content_array.into()
87}