use anyhow::Result;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
pub const DEFAULT_FORMAT: &str = "{year}/{month}/{day}/{filename}.{extension}";
const APP_NAME: &str = "exifmv";
#[derive(Debug, Default, Deserialize, Serialize)]
#[serde(default, rename_all = "kebab-case")]
pub struct Config {
pub format: Option<String>,
pub make_lowercase: Option<bool>,
pub recursive: Option<bool>,
pub day_wrap: Option<String>,
pub verbose: Option<bool>,
pub halt_on_errors: Option<bool>,
pub dereference: Option<bool>,
pub checksum: Option<bool>,
}
impl Config {
pub fn load(path: Option<&PathBuf>) -> Result<Self> {
if let Some(path) = path {
Ok(confy::load_path(path)?)
} else {
Ok(confy::load(APP_NAME, "config")?)
}
}
pub fn format(&self) -> &str {
self.format.as_deref().unwrap_or(DEFAULT_FORMAT)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parse_config() {
let toml = r#"
format = "{year}-{month}-{day}/{filename}.{extension}"
make-lowercase = true
day-wrap = "04:00"
verbose = false
"#;
let config: Config = toml::from_str(toml).unwrap();
assert_eq!(
config.format.as_deref(),
Some("{year}-{month}-{day}/{filename}.{extension}")
);
assert_eq!(config.make_lowercase, Some(true));
assert_eq!(config.day_wrap.as_deref(), Some("04:00"));
assert_eq!(config.verbose, Some(false));
}
#[test]
fn empty_config() {
let config: Config = toml::from_str("").unwrap();
assert!(config.format.is_none());
assert!(config.make_lowercase.is_none());
}
}