1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
extern crate proc_macro;
use proc_macro2::Span;
use proc_quote::quote;
use syn::Ident;
#[proc_macro]
pub fn supermod(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
let path_string = if let proc_macro::TokenTree::Literal(lit) = item.into_iter().next().unwrap() { lit.to_string() } else { panic!() };
let path = &path_string[1..path_string.len() - 1];
let module_name = Ident::new(&path[path.find("/").map(|x| x + 1).unwrap_or(0)..], Span::call_site());
let idents = std::fs::read_dir(path).unwrap().map(|x| {
let path = x.unwrap().path();
let name = path.file_stem().unwrap().to_string_lossy();
Ident::new(&name, Span::call_site())
}).collect::<Vec<_>>();
proc_macro::TokenStream::from(quote!(
mod #module_name { #(pub mod #idents;)* }
pub use #module_name::{
#(#idents,)*
};
))
}