subx_cli/cli/
match_args.rs1#![allow(clippy::needless_borrows_for_generic_args)]
2use crate::cli::InputPathHandler;
5use crate::error::SubXError;
6use clap::Args;
7use std::path::PathBuf;
8
9#[derive(Args, Debug)]
11pub struct MatchArgs {
12 pub path: Option<PathBuf>,
14
15 #[arg(short = 'i', long = "input", value_name = "PATH")]
17 pub input_paths: Vec<PathBuf>,
18
19 #[arg(long)]
21 pub dry_run: bool,
22
23 #[arg(long, default_value = "80", value_parser = clap::value_parser!(u8).range(0..=100))]
25 pub confidence: u8,
26
27 #[arg(short, long)]
29 pub recursive: bool,
30
31 #[arg(long)]
33 pub backup: bool,
34
35 #[arg(long, short = 'c')]
37 pub copy: bool,
38
39 #[arg(long = "move", short = 'm')]
41 pub move_files: bool,
42
43 #[arg(long, default_value_t = false)]
45 pub no_extract: bool,
46}
47
48impl MatchArgs {
49 pub fn validate(&self) -> Result<(), String> {
51 if self.copy && self.move_files {
52 return Err(
53 "Cannot use --copy and --move together. Please choose one operation mode."
54 .to_string(),
55 );
56 }
57 Ok(())
58 }
59
60 pub fn get_input_handler(&self) -> Result<InputPathHandler, SubXError> {
62 let optional_paths = vec![self.path.clone()];
63 let merged_paths = InputPathHandler::merge_paths_from_multiple_sources(
64 &optional_paths,
65 &self.input_paths,
66 &[],
67 )?;
68
69 Ok(InputPathHandler::from_args(&merged_paths, self.recursive)?
70 .with_extensions(&["mp4", "mkv", "avi", "mov", "srt", "ass", "vtt", "sub"])
71 .with_no_extract(self.no_extract))
72 }
73}
74
75#[cfg(test)]
77mod tests {
78 use crate::cli::{Cli, Commands};
79 use clap::Parser;
80 use std::path::PathBuf;
81
82 #[test]
83 fn test_match_args_default_values() {
84 let cli = Cli::try_parse_from(&["subx-cli", "match", "path"]).unwrap();
85 let args = match cli.command {
86 Commands::Match(m) => m,
87 _ => panic!("Expected Match command"),
88 };
89 assert_eq!(args.path, Some(PathBuf::from("path")));
90 assert!(args.input_paths.is_empty());
91 assert!(!args.dry_run);
92 assert!(!args.recursive);
93 assert!(!args.backup);
94 assert_eq!(args.confidence, 80);
95 }
96
97 #[test]
98 fn test_match_args_parsing() {
99 let cli = Cli::try_parse_from(&[
100 "subx-cli",
101 "match",
102 "path",
103 "--dry-run",
104 "--recursive",
105 "--backup",
106 "--confidence",
107 "50",
108 ])
109 .unwrap();
110 let args = match cli.command {
111 Commands::Match(m) => m,
112 _ => panic!("Expected Match command"),
113 };
114 assert_eq!(args.path, Some(PathBuf::from("path")));
115 assert!(args.input_paths.is_empty());
116 assert!(args.dry_run);
117 assert!(args.recursive);
118 assert!(args.backup);
119 assert_eq!(args.confidence, 50);
120 }
121
122 #[test]
123 fn test_match_args_invalid_confidence() {
124 let res = Cli::try_parse_from(&["subx-cli", "match", "path", "--confidence", "150"]);
125 assert!(res.is_err());
126 }
127
128 #[test]
129 fn test_match_args_copy_and_move_mutually_exclusive() {
130 let cli = Cli::try_parse_from(&["subx-cli", "match", "path", "--copy", "--move"]).unwrap();
131 let args = match cli.command {
132 Commands::Match(m) => m,
133 _ => panic!("Expected Match command"),
134 };
135 let result = args.validate();
136 assert!(result.is_err());
137 assert!(
138 result
139 .unwrap_err()
140 .contains("Cannot use --copy and --move together")
141 );
142 }
143
144 #[test]
145 fn test_match_args_copy_parameter() {
146 let cli = Cli::try_parse_from(&["subx-cli", "match", "path", "--copy"]).unwrap();
147 let args = match cli.command {
148 Commands::Match(m) => m,
149 _ => panic!("Expected Match command"),
150 };
151 assert!(args.copy);
152 assert!(!args.move_files);
153 assert!(args.validate().is_ok());
154 }
155
156 #[test]
157 fn test_match_args_move_parameter() {
158 let cli = Cli::try_parse_from(&["subx-cli", "match", "path", "--move"]).unwrap();
159 let args = match cli.command {
160 Commands::Match(m) => m,
161 _ => panic!("Expected Match command"),
162 };
163 assert!(!args.copy);
164 assert!(args.move_files);
165 assert!(args.validate().is_ok());
166 }
167
168 #[test]
169 fn test_match_args_input_paths() {
170 let cli = Cli::try_parse_from(&[
171 "subx-cli",
172 "match",
173 "-i",
174 "dir1",
175 "-i",
176 "dir2",
177 "--recursive",
178 ])
179 .unwrap();
180 let args = match cli.command {
181 Commands::Match(m) => m,
182 _ => panic!("Expected Match command"),
183 };
184 assert!(args.path.is_none());
185 assert_eq!(
186 args.input_paths,
187 vec![PathBuf::from("dir1"), PathBuf::from("dir2")]
188 );
189 assert!(args.recursive);
190 }
191}