#![allow(clippy::needless_borrows_for_generic_args)]
use crate::cli::InputPathHandler;
use crate::error::SubXError;
use clap::Args;
use std::path::PathBuf;
#[derive(Args, Debug)]
pub struct MatchArgs {
pub path: Option<PathBuf>,
#[arg(short = 'i', long = "input", value_name = "PATH")]
pub input_paths: Vec<PathBuf>,
#[arg(long)]
pub dry_run: bool,
#[arg(long, default_value = "80", value_parser = clap::value_parser!(u8).range(0..=100))]
pub confidence: u8,
#[arg(short, long)]
pub recursive: bool,
#[arg(long)]
pub backup: bool,
#[arg(long, short = 'c')]
pub copy: bool,
#[arg(long = "move", short = 'm')]
pub move_files: bool,
#[arg(long, default_value_t = false)]
pub no_extract: bool,
}
impl MatchArgs {
pub fn validate(&self) -> Result<(), String> {
if self.copy && self.move_files {
return Err(
"Cannot use --copy and --move together. Please choose one operation mode."
.to_string(),
);
}
Ok(())
}
pub fn get_input_handler(&self) -> Result<InputPathHandler, SubXError> {
let optional_paths = vec![self.path.clone()];
let merged_paths = InputPathHandler::merge_paths_from_multiple_sources(
&optional_paths,
&self.input_paths,
&[],
)?;
Ok(InputPathHandler::from_args(&merged_paths, self.recursive)?
.with_extensions(&["mp4", "mkv", "avi", "mov", "srt", "ass", "vtt", "sub"])
.with_no_extract(self.no_extract))
}
}
#[cfg(test)]
mod tests {
use crate::cli::{Cli, Commands};
use clap::Parser;
use std::path::PathBuf;
#[test]
fn test_match_args_default_values() {
let cli = Cli::try_parse_from(&["subx-cli", "match", "path"]).unwrap();
let args = match cli.command {
Commands::Match(m) => m,
_ => panic!("Expected Match command"),
};
assert_eq!(args.path, Some(PathBuf::from("path")));
assert!(args.input_paths.is_empty());
assert!(!args.dry_run);
assert!(!args.recursive);
assert!(!args.backup);
assert_eq!(args.confidence, 80);
}
#[test]
fn test_match_args_parsing() {
let cli = Cli::try_parse_from(&[
"subx-cli",
"match",
"path",
"--dry-run",
"--recursive",
"--backup",
"--confidence",
"50",
])
.unwrap();
let args = match cli.command {
Commands::Match(m) => m,
_ => panic!("Expected Match command"),
};
assert_eq!(args.path, Some(PathBuf::from("path")));
assert!(args.input_paths.is_empty());
assert!(args.dry_run);
assert!(args.recursive);
assert!(args.backup);
assert_eq!(args.confidence, 50);
}
#[test]
fn test_match_args_invalid_confidence() {
let res = Cli::try_parse_from(&["subx-cli", "match", "path", "--confidence", "150"]);
assert!(res.is_err());
}
#[test]
fn test_match_args_copy_and_move_mutually_exclusive() {
let cli = Cli::try_parse_from(&["subx-cli", "match", "path", "--copy", "--move"]).unwrap();
let args = match cli.command {
Commands::Match(m) => m,
_ => panic!("Expected Match command"),
};
let result = args.validate();
assert!(result.is_err());
assert!(
result
.unwrap_err()
.contains("Cannot use --copy and --move together")
);
}
#[test]
fn test_match_args_copy_parameter() {
let cli = Cli::try_parse_from(&["subx-cli", "match", "path", "--copy"]).unwrap();
let args = match cli.command {
Commands::Match(m) => m,
_ => panic!("Expected Match command"),
};
assert!(args.copy);
assert!(!args.move_files);
assert!(args.validate().is_ok());
}
#[test]
fn test_match_args_move_parameter() {
let cli = Cli::try_parse_from(&["subx-cli", "match", "path", "--move"]).unwrap();
let args = match cli.command {
Commands::Match(m) => m,
_ => panic!("Expected Match command"),
};
assert!(!args.copy);
assert!(args.move_files);
assert!(args.validate().is_ok());
}
#[test]
fn test_match_args_input_paths() {
let cli = Cli::try_parse_from(&[
"subx-cli",
"match",
"-i",
"dir1",
"-i",
"dir2",
"--recursive",
])
.unwrap();
let args = match cli.command {
Commands::Match(m) => m,
_ => panic!("Expected Match command"),
};
assert!(args.path.is_none());
assert_eq!(
args.input_paths,
vec![PathBuf::from("dir1"), PathBuf::from("dir2")]
);
assert!(args.recursive);
}
}