algosul_core/codegen/
module.rs1use 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 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}