algosul_core/codegen/
module.rs

1use std::{
2    env,
3    path::{Path, PathBuf},
4};
5
6use glob::PatternError;
7use proc_macro2::Ident;
8use syn::{parse_quote, token::Brace, Item, ItemMod};
9pub trait ModuleExt {
10    /// 添加元素
11    fn add_item(&mut self, item: Item) -> &mut Self;
12    fn add_item_by_glob<F: Fn(&Path) -> Item>(
13        &mut self, pattern: &str, f: F,
14    ) -> Result<&mut Self, PatternError> {
15        let manifest_dir =
16            PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
17        let full_pattern = manifest_dir.join(pattern);
18        let pattern_str = full_pattern.to_str().unwrap();
19        for entry in glob::glob(pattern_str)? {
20            let entry = entry.unwrap();
21            let rel_path = entry.strip_prefix(&manifest_dir).unwrap();
22            self.add_item(f(rel_path));
23        }
24        Ok(self)
25    }
26    fn add_include_str_by_glob<F: Fn(&Path) -> Ident>(
27        &mut self, pattern: &str, f: F,
28    ) -> Result<&mut Self, PatternError> {
29        self.add_item_by_glob(pattern, |entry| {
30            let ident = f(entry);
31            let entry = entry.to_str().unwrap();
32            parse_quote!(
33                pub const #ident: &str = include_str!(
34                    concat!(env!("CARGO_MANIFEST_DIR"), "/", #entry)
35                );
36            )
37        })
38    }
39    fn add_include_byte_by_glob<F: Fn(&Path) -> Ident>(
40        &mut self, pattern: &str, f: F,
41    ) -> Result<&mut Self, PatternError> {
42        self.add_item_by_glob(pattern, |entry| {
43            let ident = f(entry);
44            let entry = entry.to_str().unwrap();
45            parse_quote!(
46                pub const #ident: &[u8] = include_byte!(
47                    concat!(env!("CARGO_MANIFEST_DIR"), "/", #entry)
48                );
49            )
50        })
51    }
52}
53impl ModuleExt for ItemMod {
54    fn add_item(&mut self, item: Item) -> &mut Self {
55        self.content
56            .get_or_insert_with(|| (Brace::default(), Vec::new()))
57            .1
58            .push(item);
59        self
60    }
61}