use crate::cfg::Config;
use crate::cli::Cli;
use anyhow::anyhow;
use std::path::PathBuf;
#[derive(Debug, PartialEq, Eq)]
pub struct Params {
pub dir: PathBuf,
pub filename: String,
pub backup_dir: PathBuf,
pub always_skip: bool,
pub always_backup: bool,
}
impl Params {
pub fn new(cli: Cli, cfg: Config) -> anyhow::Result<Self> {
if cfg.backup_dir.is_relative() {
return Err(anyhow!("Got a relative path for backup_dir in the configuration file, but backup_dir should be absolute."));
}
assert!(!(cli.always_skip && cli.always_backup));
if cfg.always_skip && cfg.always_backup {
return Err(anyhow!("Got always_skip and always_backup set to true in the configuration file, but only one of them can be true."));
}
let filename = cli.filename.unwrap_or(cfg.filename);
let backup_dir = cli.backup_dir.unwrap_or(cfg.backup_dir);
let mut always_skip = cli.always_skip;
let mut always_backup = cli.always_backup;
if !(always_skip || always_backup) {
always_skip = cfg.always_skip;
always_backup = cfg.always_backup;
}
Ok(Params {
dir: cli.dir,
filename,
backup_dir,
always_skip,
always_backup,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[derive(Debug)]
struct TestCase {
cli: Cli,
cfg: Config,
params: Params,
}
#[test]
fn cli_takes_precedence_on_config() {
let test_cases = vec![
TestCase {
cli: Cli {
dir: PathBuf::from("dir"),
filename: Some(String::from("cli_filename")),
backup_dir: Some(PathBuf::from("/cli/backup/dir")),
always_skip: false,
always_backup: true,
},
cfg: Config {
filename: String::from("cfg_filename"),
backup_dir: PathBuf::from("/cfg/backup/dir"),
always_skip: true,
always_backup: false,
},
params: Params {
dir: PathBuf::from("dir"),
filename: String::from("cli_filename"),
backup_dir: PathBuf::from("/cli/backup/dir"),
always_skip: false,
always_backup: true,
},
},
TestCase {
cli: Cli {
dir: PathBuf::from("dir"),
filename: None,
backup_dir: None,
always_skip: false,
always_backup: false,
},
cfg: Config {
filename: String::from("cfg_filename"),
backup_dir: PathBuf::from("/cfg/backup/dir"),
always_skip: true,
always_backup: false,
},
params: Params {
dir: PathBuf::from("dir"),
filename: String::from("cfg_filename"),
backup_dir: PathBuf::from("/cfg/backup/dir"),
always_skip: true,
always_backup: false,
},
},
TestCase {
cli: Cli {
dir: PathBuf::from("dir"),
filename: Some(String::from("cli_filename")),
backup_dir: None,
always_skip: false,
always_backup: false,
},
cfg: Config {
filename: String::from("cfg_filename"),
backup_dir: PathBuf::from("/cfg/backup/dir"),
always_skip: true,
always_backup: false,
},
params: Params {
dir: PathBuf::from("dir"),
filename: String::from("cli_filename"),
backup_dir: PathBuf::from("/cfg/backup/dir"),
always_skip: true,
always_backup: false,
},
},
];
for test_case in test_cases {
let params = Params::new(test_case.cli, test_case.cfg).expect(
"Params::new should have succeed. There must be an error in the test case.",
);
assert_eq!(
params, test_case.params,
"Expected {:?}, but got {:?}",
test_case.params, params
);
}
}
}