dyn_import/
lib.rs

1extern crate proc_macro;
2use proc_macro::TokenStream;
3use quote::{format_ident, quote};
4use std::fs;
5use syn::{parse_macro_input, LitStr};
6
7#[macro_use]
8mod macros;
9
10#[proc_macro]
11pub fn import_mods(input: TokenStream) -> TokenStream {
12    let input = parse_macro_input!(input as LitStr).value();
13
14    let mut from_dir = get_cwd!().expect("Couldn't get the CWD");
15
16    for part in input.split(&['/', '\\'][..]) {
17        from_dir = from_dir.join(part);
18    }
19
20    if !from_dir.exists() {
21        panic!("Path doesn't exist: {:?}", from_dir)
22    }
23
24    let mut generated = quote! {};
25
26    for entry in fs::read_dir(from_dir).expect("Failed to read directory") {
27        if let Ok(entry) = entry {
28            let entry_path = entry.path();
29
30            if entry_path.is_file() {
31                if entry_path.extension().unwrap() != "rs"
32                    || entry_path.file_name().unwrap() == "mod.rs"
33                {
34                    continue;
35                }
36            } else {
37                let file_path = entry_path.join("mod.rs");
38                if !file_path.exists() {
39                    continue;
40                }
41            }
42            let filename = entry_path
43                .file_stem()
44                .unwrap()
45                .to_string_lossy()
46                .to_string();
47            let mod_name = format_ident!("{}", filename);
48            let mod_des = quote! {
49                pub mod #mod_name;
50            };
51            generated.extend(mod_des);
52        }
53    }
54    generated.into()
55}