1use indoc::formatdoc;
2use std::{fs, path::Path};
3
4pub struct Config {
9 pub vbare: vbare_gen::Config,
11}
12
13impl Default for Config {
14 fn default() -> Self {
15 Self {
16 vbare: vbare_gen::Config::default(),
17 }
18 }
19}
20
21pub fn process_schemas(schema_dir: &Path) -> Result<(), Box<dyn std::error::Error>> {
23 process_schemas_with_config(schema_dir, &Config::default())
24}
25
26pub fn process_schemas_with_config(
28 schema_dir: &Path,
29 config: &Config,
30) -> Result<(), Box<dyn std::error::Error>> {
31 let out_dir = std::env::var("OUT_DIR")?;
32 let out_path = Path::new(&out_dir);
33
34 println!("cargo:rerun-if-changed={}", schema_dir.display());
35
36 let mut all_names = Vec::new();
37
38 for entry in fs::read_dir(schema_dir)?.flatten() {
39 let path = entry.path();
40
41 if path.is_dir() {
42 continue;
43 }
44
45 let bare_name = path
46 .file_name()
47 .ok_or("No file name")?
48 .to_str()
49 .ok_or("Invalid UTF-8 in file name")?
50 .rsplit_once('.')
51 .ok_or("No file extension")?
52 .0;
53
54 let tokens = vbare_gen::bare_schema(&path, config.vbare);
55 let ast = syn::parse2(tokens)?;
56 let content = prettyplease::unparse(&ast);
57
58 fs::write(out_path.join(format!("{bare_name}_generated.rs")), content)?;
59
60 all_names.push(bare_name.to_string());
61 }
62
63 let mut mod_content = String::new();
64 mod_content.push_str("// Auto-generated module file for schemas\n\n");
65
66 for name in all_names {
67 let module_name = name.replace('.', "_");
68 mod_content.push_str(&formatdoc!(
69 r#"
70 pub mod {module_name} {{
71 include!(concat!(env!("OUT_DIR"), "/{name}_generated.rs"));
72 }}
73 "#,
74 name = name,
75 module_name = module_name,
76 ));
77 }
78
79 fs::write(out_path.join("combined_imports.rs"), mod_content)?;
80
81 Ok(())
82}