use std::fs;
use std::io::Write;
use std::path::Path;
use fs2::FileExt;
include!(concat!(env!("OUT_DIR"), "/embedded_data.rs"));
pub(crate) fn ensure_installed(dir: &Path) -> crate::Result<()> {
let stamp = dir.join("VERSION");
if let Ok(existing) = fs::read_to_string(&stamp) {
if existing.trim() == VERSION {
return Ok(());
}
}
fs::create_dir_all(dir)?;
let lock_path = dir.join(".install.lock");
let lock = fs::OpenOptions::new()
.create(true)
.write(true)
.truncate(false)
.open(&lock_path)?;
lock.lock_exclusive()?;
if let Ok(existing) = fs::read_to_string(&stamp) {
if existing.trim() == VERSION {
let _ = FileExt::unlock(&lock);
return Ok(());
}
}
for (name, payload, compressed) in FILES {
let path = dir.join(name);
let bytes: std::borrow::Cow<'_, [u8]> = if *compressed {
let decoded = zstd::decode_all(*payload).map_err(crate::Error::Io)?;
std::borrow::Cow::Owned(decoded)
} else {
std::borrow::Cow::Borrowed(*payload)
};
let mut f = fs::File::create(&path)?;
f.write_all(&bytes)?;
f.sync_all().ok();
}
fs::write(&stamp, VERSION)?;
let _ = FileExt::unlock(&lock);
Ok(())
}