use std::{fs::create_dir_all, io::Write, path::PathBuf}; use config::{File, Map}; use serde::{Deserialize, Serialize}; use tracing::{debug, trace}; #[derive(Debug, Serialize, Deserialize)] #[serde(default)] pub struct Config { pub root: String, pub directories: Vec, pub custom_directories: Map, pub device: String, } impl Default for Config { fn default() -> Self { Self { root: "/mnt/backup".to_string(), directories: vec![], custom_directories: Map::new(), device: gethostname::gethostname() .into_string() .expect("invalid hostname string"), } } } impl Config { pub fn load(path: Option) -> core::result::Result { debug!("load config"); let source = if let Some(source) = path { source } else { Self::get_location() }; let config = config::Config::builder() .add_source(File::with_name(&source.to_string_lossy()).required(false)) .add_source(config::Environment::with_prefix("FXBAUP").separator("_")) .build()?; let cfg = config.try_deserialize(); trace!(?cfg, "loaded config"); cfg } pub fn generate() -> crate::error::Result<()> { let loc = Self::get_location(); create_dir_all(loc.parent().unwrap())?; let mut f = std::fs::File::create(loc)?; f.write_all(toml::to_string(&Self::default())?.as_bytes())?; Ok(()) } fn get_location() -> PathBuf { let mut conf_dir = dirs::config_local_dir().unwrap(); conf_dir.push("arbs"); conf_dir.push("config.toml"); conf_dir } }