I am looking for a procedural macro which is very similar to dirmod, but instead of making a simple list of module declarations, it simply makes a static array with their names:
I forgot ChatGPT existed. This is both convenient and scary:
Sure! Here's an example of how you can implement a Rust procedural macro to achieve the desired functionality:
extern crate proc_macro;
use proc_macro::TokenStream;
use quote::quote;
use std::fs;
use std::path::Path;
use syn::{parse_macro_input, LitStr};
#[proc_macro]
pub fn generate_module_list(input: TokenStream) -> TokenStream {
// Parse the input as a string literal representing the base directory path
let base_path = parse_macro_input!(input as LitStr).value();
// Generate the module list by reading the directory and collecting the module names
let module_list = fs::read_dir(base_path)
.expect("Failed to read directory")
.map(|entry| {
entry
.expect("Failed to read entry")
.file_name()
.into_string()
.expect("Failed to convert OsString to String")
})
.filter(|name| name.ends_with(".rs") && name != "mod.rs")
.collect::<Vec<String>>();
// Generate the static array of string slices
let module_array = quote! {
[
#(#module_list),*
]
};
// Generate the output as a const static array of string slices
let output = quote! {
pub const MODULE_LIST: [&str; #module_array.len()] = [#module_array];
};
// Return the output as a TokenStream
output.into()
}
To use this macro, you can include it in your Rust code as follows:
rustCopy code
use my_macro::generate_module_list;
// Specify the path to the base directory and generate the module list
generate_module_list!("base");
Note that in order to use this procedural macro, you'll need to add the my_macro crate as a dependency in your Cargo.toml and import it into your Rust code. Also, make sure to add the necessary dependencies (proc-macro2 and quote) to your Cargo.toml as well.