use std::{collections::HashMap, path::Path, str::FromStr}; use eyre::{Context, Result}; use serde::Deserialize; #[derive(Debug, Default)] pub struct Config { pub datasets: Vec, pub schedules: Vec, } impl Config { pub fn dataset(&self, name: &str) -> Option<&Dataset> { self.datasets.iter().find(|d| d.name == name) } pub fn tag(&self, tag: &str) -> Option<&Schedule> { self.schedules.iter().find(|s| s.tag == tag) } } #[derive(Debug, Clone)] pub struct Dataset { pub name: String, pub schedules: Vec, pub recursive: bool, } impl Dataset { pub fn has_tag(&self, tag: &str) -> bool { self.schedules.iter().any(|s| s == tag) } } #[derive(Debug, Clone)] pub struct Schedule { pub tag: String, pub cron: cron::Schedule, pub keep: usize, } #[derive(Debug, Deserialize)] struct TomlConfig { dataset: HashMap, schedule: HashMap, } #[derive(Debug, Deserialize)] struct TomlDataset { recursive: Option, schedules: Vec, } #[derive(Debug, Deserialize)] struct TomlSchedule { cron: String, keep: usize, } pub fn read(path: &Path) -> Result { let content = std::fs::read_to_string(path)?; let config = toml::from_str::(&content)?; let mut datasets = Vec::new(); let mut schedules = Vec::new(); for (name, dataset) in config.dataset { let schedules = dataset.schedules; let recursive = dataset.recursive; datasets.push(Dataset { name, schedules, recursive: recursive.unwrap_or_default(), }); } for (name, schedule) in config.schedule { let cron = cron::Schedule::from_str(&schedule.cron) .with_context(|| format!("parsing cron schedule: '{}'", &schedule.cron))?; let keep = schedule.keep; schedules.push(Schedule { tag: name, cron, keep }); } Ok(Config { datasets, schedules, }) }