use std::path::{Path, PathBuf};
#[derive(Debug, Clone)]
pub struct Workdir {
root: PathBuf,
}
impl Workdir {
pub fn new(root: impl Into<PathBuf>) -> Self {
Self { root: root.into() }
}
pub fn root(&self) -> &Path {
&self.root
}
pub fn csv_dir(&self) -> PathBuf {
self.root.join("csv")
}
pub fn csv_path(&self, stem: &str) -> PathBuf {
self.csv_dir().join(format!("{stem}.csv"))
}
pub fn index_file(&self) -> PathBuf {
self.root.join("sodir_index.json")
}
pub fn complement_file(&self) -> PathBuf {
self.root.join("blueprint_complement.json")
}
pub fn compiled_blueprint(&self) -> PathBuf {
self.root.join("_compiled_blueprint.json")
}
pub fn graph_dir(&self) -> PathBuf {
self.root.join("graph")
}
pub fn disk_graph_meta(&self) -> PathBuf {
self.graph_dir().join("disk_graph_meta.json")
}
pub fn source_meta(&self) -> PathBuf {
self.graph_dir().join("sodir_source.json")
}
pub fn graph_exists(&self) -> bool {
self.disk_graph_meta().is_file()
}
pub fn disk_graph_age_days(&self) -> Option<f64> {
crate::datasets::sodir::index::file_mtime_age_days(&self.disk_graph_meta())
}
pub fn ensure_dirs(&self) -> std::io::Result<()> {
std::fs::create_dir_all(self.csv_dir())?;
std::fs::create_dir_all(self.graph_dir())?;
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn paths_are_well_formed() {
let w = Workdir::new("/tmp/sodir");
assert_eq!(w.csv_dir(), Path::new("/tmp/sodir/csv"));
assert_eq!(w.csv_path("field"), Path::new("/tmp/sodir/csv/field.csv"));
assert_eq!(w.index_file(), Path::new("/tmp/sodir/sodir_index.json"));
assert_eq!(w.graph_dir(), Path::new("/tmp/sodir/graph"));
assert_eq!(
w.disk_graph_meta(),
Path::new("/tmp/sodir/graph/disk_graph_meta.json")
);
}
#[test]
fn ensure_dirs_idempotent_and_graph_probe() {
let tmp = tempfile::tempdir().unwrap();
let w = Workdir::new(tmp.path());
assert!(!w.graph_exists());
w.ensure_dirs().unwrap();
w.ensure_dirs().unwrap(); assert!(w.csv_dir().is_dir());
assert!(w.graph_dir().is_dir());
assert!(!w.graph_exists()); }
}