use std::{env, fs, io::Result, path};
const PRIM_DIR: &str = "CALYX_PRIMITIVES_DIR";
struct PrimState {
base: path::PathBuf,
old_prims: Option<path::PathBuf>,
new_prims: path::PathBuf,
}
fn move_primitives() -> Result<PrimState> {
let base: path::PathBuf = match env::var_os(PRIM_DIR) {
Some(v) => path::PathBuf::from(v),
None => {
let mut path: path::PathBuf = env::var_os("HOME").unwrap().into();
path.push(".calyx");
path
}
};
let mut prims = base.clone();
prims.push("primitives");
let old_prims = if prims.exists() {
let mut old_prims = base.clone();
old_prims.push("old_primitives");
if old_prims.exists() {
fs::remove_dir_all(&old_prims)?;
}
match fs::rename(&prims, &old_prims) {
Ok(_) => (),
Err(e) => {
println!(
"cargo:warning=Failed to move primitives directory: {e}"
);
return Err(e);
}
};
Some(old_prims)
} else {
None
};
fs::create_dir_all(&prims)?;
Ok(PrimState {
base,
old_prims,
new_prims: prims,
})
}
fn write_primitive(prims: &path::Path) -> Result<()> {
for (loc, src) in calyx_stdlib::KNOWN_LIBS
.into_iter()
.flat_map(|(_, info)| info)
.chain(Some(calyx_stdlib::COMPILE_LIB))
{
let mut path = prims.to_owned().clone();
path.push(loc);
fs::create_dir_all(path.parent().unwrap())?;
match fs::write(path, src) {
Ok(_) => (),
Err(e) => {
println!(
"cargo:warning=Failed to write primitive: {loc}. Error: {e}"
);
return Err(e);
}
}
}
Ok(())
}
fn create_primitives() -> Result<path::PathBuf> {
let PrimState {
base,
old_prims,
new_prims: prims,
} = move_primitives()?;
match write_primitive(prims.as_path()) {
Ok(_) => {
if let Some(old) = old_prims {
fs::remove_dir_all(old)?;
}
}
Err(e) => {
println!("cargo:warning=Failed to write primitives directory. Restoring old directory: {e}");
if let Some(old) = old_prims {
fs::rename(old, &prims)?;
}
return Err(e);
}
}
Ok(base)
}
fn main() {
println!("cargo:rerun-if-changed=src/build.rs");
println!("cargo:rerun-if-changed=src/cmdline.rs");
match create_primitives() {
Ok(p) => {
println!("cargo:rustc-env={PRIM_DIR}={}", p.to_string_lossy());
}
Err(e) => {
println!(
"cargo:warning=Failed to create the `primitives` folder. Importing `primitives` will require passing an explicit `-l` when running the Calyx compiler. Error: {e}",
);
}
}
}