use anyhow::{bail, Context, Result};
use std::fs::{self, File};
use std::path::{Path, PathBuf};
pub struct Cache {
all_versions_root: PathBuf,
root: PathBuf,
}
impl Cache {
pub fn new() -> Result<Cache> {
let all_versions_root = match dirs::cache_dir() {
Some(root) => root.join("cargo-wasi"),
None => match dirs::home_dir() {
Some(home) => home.join(".cargo-wasi"),
None => bail!("failed to find home directory, is $HOME set?"),
},
};
let root = all_versions_root.join(env!("CARGO_PKG_VERSION"));
Ok(Cache {
all_versions_root,
root,
})
}
pub fn root(&self) -> &Path {
&self.root
}
pub fn all_versions_root(&self) -> &Path {
&self.all_versions_root
}
pub fn stamp(&self, name: impl AsRef<str>) -> Stamp {
let name = name.as_ref();
assert!(!name.contains('/'));
assert!(!name.contains('\\'));
Stamp {
path: self.root().join("stamps").join(name),
}
}
}
pub struct Stamp {
path: PathBuf,
}
impl Stamp {
pub fn exists(&self) -> bool {
self.path.exists()
}
pub fn create(self) -> Result<()> {
let stamps_dir = self.path.parent().unwrap();
fs::create_dir_all(stamps_dir).with_context(|| {
format!("failed to create stamp directory: {}", stamps_dir.display())
})?;
File::create(&self.path)
.with_context(|| format!("failed to create stamp file: {}", self.path.display()))?;
Ok(())
}
pub fn ensure(self, f: impl FnOnce() -> Result<()>) -> Result<()> {
if self.exists() {
return Ok(());
}
f()?;
self.create()
}
}