use serde::Deserialize;
use std::fs;
use std::path::PathBuf;
#[derive(Deserialize, Debug)]
pub struct Config {
pub sync: Vec<SyncTask>,
}
#[derive(Deserialize, Debug)]
pub struct SyncTask {
pub name: String,
pub source: PathBuf,
pub target: PathBuf,
#[serde(default)]
pub exclude: Vec<String>,
#[serde(default = "default_delete_extra")]
pub delete_extra: bool,
#[serde(default)]
pub delete_extra_exclude: Vec<String>,
}
fn default_delete_extra() -> bool {
false
}
impl Config {
pub fn from_file<P: AsRef<std::path::Path>>(path: P) -> anyhow::Result<Self> {
let path = path.as_ref();
if !path.exists() {
anyhow::bail!("Config file not found: {}", path.display());
}
let content = fs::read_to_string(path)
.map_err(|e| anyhow::anyhow!("Failed to read config file: {}", e))?;
let config: Config = toml::from_str(&content)
.map_err(|e| anyhow::anyhow!("Failed to parse config file: {}", e))?;
Ok(config)
}
pub fn find_task(&self, name: &str) -> Option<&SyncTask> {
self.sync.iter().find(|task| task.name == name)
}
}