use serde::Deserialize;
use std::fs;
#[derive(Debug, Deserialize, Clone)]
pub struct Config {
pub daemon: DaemonConfig,
pub filesystems: Vec<FilesystemPolicy>,
#[serde(default)]
pub preserve: Vec<String>,
#[serde(default)]
pub lifecycle: Vec<LifecycleRule>,
}
#[derive(Debug, Deserialize, Clone)]
pub struct DaemonConfig {
pub interval_seconds: Option<u64>,
pub health_window: Option<i32>,
pub lifecycle_interval_seconds: Option<u64>,
}
#[derive(Debug, Deserialize, Clone)]
pub struct FilesystemPolicy {
pub mount: String,
pub thresholds: Vec<Threshold>,
}
#[derive(Debug, Deserialize, Clone)]
pub struct Threshold {
pub usage_percent: u32,
#[serde(default)]
pub commands: Vec<String>,
}
#[derive(Debug, Deserialize, Clone)]
pub struct LifecycleRule {
pub pattern: String,
pub max_age_days: Option<u64>,
pub max_size_mb: Option<u64>,
pub compress_after_days: Option<u64>,
pub delete_compressed_after_days: Option<u64>,
}
impl Config {
pub fn load(path: &str) -> Result<Config, Box<dyn std::error::Error>> {
let raw = fs::read_to_string(path)
.map_err(|e| format!("cannot read '{}': {}", path, e))?;
let mut cfg: Config = serde_yaml::from_str(&raw)
.map_err(|e| format!("YAML parse error in '{}': {}", path, e))?;
for fs in &mut cfg.filesystems {
fs.thresholds.sort_by_key(|t| t.usage_percent);
for t in &fs.thresholds {
if t.usage_percent > 100 {
return Err(format!(
"mount '{}': usage_percent {} is > 100",
fs.mount, t.usage_percent
)
.into());
}
}
}
Ok(cfg)
}
}