use std::{
fs::{self, DirEntry, File},
path::PathBuf, env
};
use anyhow::Result;
mod build_ecs;
use build_ecs::*;
use codegen::Scope;
const FILENAME_PREFIX: &str ="ecs_";
fn main() -> Result<()> {
let out_dir = env::var("OUT_DIR").unwrap();
let mut ecs_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
ecs_path.push("ecs");
ecs_path.push("schemas");
let entries = fs::read_dir(ecs_path)?;
let mut mod_scope = Scope::new();
for entry in entries.flatten() {
let filename = entry.file_name().into_string().unwrap();
if filename.ends_with("yml") {
println!("reading {}", entry.path().to_str().unwrap());
let ext_index = filename.find(".yml").unwrap();
let module = handle_schema_file(&filename[0..ext_index], entry)?;
mod_scope.raw(format!("mod {FILENAME_PREFIX}{module};"));
mod_scope.import(&format!("{FILENAME_PREFIX}{module}"), "*").vis("pub");
}
}
let mut rs_name = PathBuf::from(out_dir);
rs_name.push("mod.rs");
fs::write(rs_name, mod_scope.to_string())?;
Ok(())
}
fn handle_schema_file(filetitle: &str, entry: DirEntry) -> Result<String> {
let ecs: Vec<EcsMetaEntry> = serde_yaml::from_reader(File::open(entry.path())?)?;
assert_eq!(ecs.len(), 1);
store_scope(filetitle, ecs.into_iter().next().unwrap())
}
fn store_scope(filetitle: &str, entry: EcsMetaEntry) -> Result<String> {
let out_dir = env::var("OUT_DIR").unwrap();
let mut rs_name = PathBuf::from(out_dir);
rs_name.push(format!("{FILENAME_PREFIX}{filetitle}.rs"));
let type_name = entry.name.clone();
let rs_scope = Scope::from(entry);
println!("write to {}", rs_name.to_str().unwrap());
fs::write(rs_name, rs_scope.to_string())?;
Ok(type_name)
}