use anyhow::{Context, Result};
use std::{env, fs};
use walkdir::WalkDir;
fn generate_builtin_std_library() -> Result<()> {
use std::path::PathBuf;
let manifest_dir = env::var("CARGO_MANIFEST_DIR")
.map(PathBuf::from)
.expect("Manifest dir");
let dir = env::var("MICROCAD_STD_DIR")
.map(PathBuf::from)
.unwrap_or_else(|_| manifest_dir.join("../../lib/std"));
let dest_path = env::var("OUT_DIR")
.map(PathBuf::from)
.expect("Output dir")
.join("microcad_std.rs");
let mut files = Vec::new();
for entry in WalkDir::new(&dir)
.into_iter()
.filter_map(|e| e.ok())
.filter(|e| e.path().extension().is_some_and(|ext| ext == "µcad"))
{
let path = entry.path();
let rel_path = path.strip_prefix(&dir).expect("Some prefix").to_path_buf();
let content = fs::read_to_string(path).expect("Unable to read file");
files.push((rel_path, content));
}
let mut code = String::new();
code.push_str(
"
mod microcad_std {
use std::path::PathBuf;
use std::collections::HashMap;
lazy_static::lazy_static! {
pub static ref FILES: HashMap<PathBuf, String> = {
let mut m = HashMap::new();
",
);
for (path, content) in files {
let path_str = path.to_string_lossy();
code.push_str(&format!(
" m.insert(PathBuf::from(r#\"{path_str}\"#), r#\"{content}\"#.to_string());\n"
));
}
code.push_str(
"
m
};
}
}
",
);
match rustfmt_wrapper::rustfmt(code) {
Ok(code) =>
{
fs::write(&dest_path, code).context(format!("cannot create file '{dest_path:?}'"))?;
println!("cargo:rerun-if-changed={dir}", dir = dir.display());
Ok(())
}
Err(rustfmt_wrapper::Error::Rustfmt(msg)) => {
Err(anyhow::Error::msg(msg.clone())).context(msg)
}
Err(err) => Err(anyhow::Error::new(err)),
}
}
fn main() {
generate_builtin_std_library().expect("No error");
}