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