use std::path::Path;
use anyhow::{Context, Result};
use super::definition::AuditDefinition;
pub fn load(path: &Path) -> Result<AuditDefinition> {
let raw = std::fs::read_to_string(path)
.with_context(|| format!("Cannot read audit definition file: {}", path.display()))?;
serde_yaml::from_str::<AuditDefinition>(&raw).with_context(|| {
format!(
"Audit definition file is not valid YAML or has an unexpected structure: {}",
path.display()
)
})
}
pub fn save(def: &AuditDefinition, path: &Path, backup: bool) -> Result<()> {
let _lock = super::lock::acquire(path)
.with_context(|| format!("Cannot acquire lock for {}", path.display()))?;
if backup && path.exists() {
let bak = path.with_extension("bak");
std::fs::copy(path, &bak).with_context(|| {
format!("Cannot create backup {}", bak.display())
})?;
log::info!("Backup written to {}", bak.display());
}
let yaml = serde_yaml::to_string(def)
.context("Failed to serialize audit definition to YAML")?;
let tmp = path.with_extension("tmp");
std::fs::write(&tmp, yaml.as_bytes())
.with_context(|| format!("Cannot write to temp file {}", tmp.display()))?;
std::fs::rename(&tmp, path).with_context(|| {
format!(
"Cannot rename {} → {}",
tmp.display(),
path.display()
)
})?;
log::info!("Audit definition saved to {}", path.display());
Ok(())
}