use std::path::PathBuf; use clap::Parser; #[derive(Debug, Clone, Parser)] #[command(name = "meterbox", about = "Host resource usage dashboard")] pub struct Config { /// Bind address — default localhost only (safe behind Caddy/Rathole) #[arg(long, env = "METERBOX_LISTEN", default_value = "127.0.0.1:8787")] pub listen: String, /// SQLite database path #[arg(long, env = "METERBOX_DB", default_value = "data/meterbox.db")] pub db_path: PathBuf, /// Directory with built React assets #[arg(long, env = "METERBOX_STATIC", default_value = "frontend/dist")] pub static_dir: PathBuf, /// Sample interval in seconds #[arg(long, env = "METERBOX_INTERVAL_SECS", default_value_t = 30)] pub interval_secs: u64, /// Retain samples for this many days (max ~3 months) #[arg(long, env = "METERBOX_RETENTION_DAYS", default_value_t = 90)] pub retention_days: i64, /// Hard cap for SQLite on-disk size (main + WAL + SHM), bytes. Default 10 GiB. #[arg(long, env = "METERBOX_MAX_DB_BYTES", default_value_t = 10 * 1024 * 1024 * 1024)] pub max_db_bytes: u64, /// How often the cleanup job runs (seconds). Default 1 hour. #[arg(long, env = "METERBOX_CLEANUP_INTERVAL_SECS", default_value_t = 3600)] pub cleanup_interval_secs: u64, } impl Config { pub fn ensure_dirs(&self) -> anyhow::Result<()> { if let Some(parent) = self.db_path.parent() { if !parent.as_os_str().is_empty() { std::fs::create_dir_all(parent)?; } } Ok(()) } }