subx_cli/commands/
dispatcher.rs1use crate::{Result, cli::Commands, config::ConfigService};
2use std::sync::Arc;
3
4pub async fn dispatch_command(
52 command: Commands,
53 config_service: Arc<dyn ConfigService>,
54) -> Result<()> {
55 match command {
56 Commands::Match(args) => {
57 crate::commands::match_command::execute_with_config(args, config_service).await
58 }
59 Commands::Convert(args) => {
60 crate::commands::convert_command::execute_with_config(args, config_service).await
61 }
62 Commands::Sync(args) => {
63 crate::commands::sync_command::execute_with_config(args, config_service).await
64 }
65 Commands::Config(args) => {
66 crate::commands::config_command::execute_with_config(args, config_service).await
67 }
68 Commands::GenerateCompletion(args) => {
69 let mut cmd = <crate::cli::Cli as clap::CommandFactory>::command();
70 let cmd_name = cmd.get_name().to_string();
71 let mut stdout = std::io::stdout();
72 clap_complete::generate(args.shell, &mut cmd, cmd_name, &mut stdout);
73 Ok(())
74 }
75 Commands::Cache(args) => {
76 crate::commands::cache_command::execute_with_config(args, config_service).await
77 }
78 Commands::DetectEncoding(args) => {
79 crate::commands::detect_encoding_command::detect_encoding_command_with_config(
80 args,
81 config_service.as_ref(),
82 )?;
83 Ok(())
84 }
85 }
86}
87
88pub async fn dispatch_command_with_ref(
93 command: Commands,
94 config_service: &dyn ConfigService,
95) -> Result<()> {
96 match command {
97 Commands::Match(args) => {
98 args.validate()
99 .map_err(crate::error::SubXError::CommandExecution)?;
100 crate::commands::match_command::execute(args, config_service).await
101 }
102 Commands::Convert(args) => {
103 crate::commands::convert_command::execute(args, config_service).await
104 }
105 Commands::Sync(args) => crate::commands::sync_command::execute(args, config_service).await,
106 Commands::Config(args) => {
107 crate::commands::config_command::execute(args, config_service).await
108 }
109 Commands::GenerateCompletion(args) => {
110 let mut cmd = <crate::cli::Cli as clap::CommandFactory>::command();
111 let cmd_name = cmd.get_name().to_string();
112 let mut stdout = std::io::stdout();
113 clap_complete::generate(args.shell, &mut cmd, cmd_name, &mut stdout);
114 Ok(())
115 }
116 Commands::Cache(args) => crate::commands::cache_command::execute(args).await,
117 Commands::DetectEncoding(args) => {
118 crate::commands::detect_encoding_command::detect_encoding_command_with_config(
119 args,
120 config_service,
121 )?;
122 Ok(())
123 }
124 }
125}
126
127#[cfg(test)]
128mod tests {
129 use super::*;
130 use crate::cli::{ConvertArgs, MatchArgs, OutputSubtitleFormat};
131 use crate::config::TestConfigService;
132
133 #[tokio::test]
134 async fn test_dispatch_match_command() {
135 let config_service = Arc::new(TestConfigService::with_ai_settings(
136 "test_provider",
137 "test_model",
138 ));
139 let args = MatchArgs {
140 path: Some("/tmp/test".into()),
141 input_paths: vec![],
142 dry_run: true,
143 confidence: 80,
144 recursive: false,
145 backup: false,
146 copy: false,
147 move_files: false,
148 };
149
150 let result = dispatch_command(Commands::Match(args), config_service).await;
152
153 match result {
156 Ok(_) => {} Err(e) => {
158 let error_msg = format!("{:?}", e);
160 assert!(
161 error_msg.contains("NotFound")
162 || error_msg.contains("No subtitle files found")
163 || error_msg.contains("No video files found")
164 || error_msg.contains("Config"),
165 "Unexpected error: {:?}",
166 e
167 );
168 }
169 }
170 }
171
172 #[tokio::test]
173 async fn test_dispatch_convert_command() {
174 let config_service = Arc::new(TestConfigService::with_defaults());
175 let args = ConvertArgs {
176 input: Some("/tmp/nonexistent".into()),
177 input_paths: vec![],
178 recursive: false,
179 format: Some(OutputSubtitleFormat::Srt),
180 output: None,
181 keep_original: false,
182 encoding: "utf-8".to_string(),
183 };
184
185 let _result = dispatch_command(Commands::Convert(args), config_service).await;
187 }
189
190 #[tokio::test]
191 async fn test_dispatch_with_ref() {
192 let config_service = TestConfigService::with_ai_settings("test_provider", "test_model");
193 let args = MatchArgs {
194 path: Some("/tmp/test".into()),
195 input_paths: vec![],
196 dry_run: true,
197 confidence: 80,
198 recursive: false,
199 backup: false,
200 copy: false,
201 move_files: false,
202 };
203
204 let result = dispatch_command_with_ref(Commands::Match(args), &config_service).await;
206
207 match result {
208 Ok(_) => {} Err(e) => {
210 let error_msg = format!("{:?}", e);
212 assert!(
213 error_msg.contains("NotFound")
214 || error_msg.contains("No subtitle files found")
215 || error_msg.contains("No video files found")
216 || error_msg.contains("Config"),
217 "Unexpected error: {:?}",
218 e
219 );
220 }
221 }
222 }
223}