subx_cli/config/
builder.rs1use crate::config::test_service::TestConfigService;
7use crate::config::{Config, OverflowStrategy};
8
9pub struct TestConfigBuilder {
26 config: Config,
27}
28
29impl TestConfigBuilder {
30 pub fn new() -> Self {
32 Self {
33 config: Config::default(),
34 }
35 }
36
37 pub fn with_ai_provider(mut self, provider: &str) -> Self {
45 self.config.ai.provider = provider.to_string();
46 self
47 }
48
49 pub fn with_ai_model(mut self, model: &str) -> Self {
55 self.config.ai.model = model.to_string();
56 self
57 }
58
59 pub fn with_ai_api_key(mut self, api_key: &str) -> Self {
65 self.config.ai.api_key = Some(api_key.to_string());
66 self
67 }
68
69 pub fn with_ai_base_url(mut self, base_url: &str) -> Self {
75 self.config.ai.base_url = base_url.to_string();
76 self
77 }
78
79 pub fn with_max_sample_length(mut self, length: usize) -> Self {
85 self.config.ai.max_sample_length = length;
86 self
87 }
88
89 pub fn with_ai_temperature(mut self, temperature: f32) -> Self {
95 self.config.ai.temperature = temperature;
96 self
97 }
98
99 pub fn with_ai_retry(mut self, attempts: u32, delay_ms: u64) -> Self {
106 self.config.ai.retry_attempts = attempts;
107 self.config.ai.retry_delay_ms = delay_ms;
108 self
109 }
110
111 pub fn with_sync_threshold(mut self, threshold: f32) -> Self {
119 self.config.sync.correlation_threshold = threshold;
120 self
121 }
122
123 pub fn with_max_offset(mut self, offset: f32) -> Self {
129 self.config.sync.max_offset_seconds = offset;
130 self
131 }
132
133 pub fn with_audio_sample_rate(mut self, sample_rate: u32) -> Self {
139 self.config.sync.audio_sample_rate = sample_rate;
140 self
141 }
142
143 pub fn with_dialogue_detection(mut self, enabled: bool) -> Self {
149 self.config.sync.enable_dialogue_detection = enabled;
150 self
151 }
152
153 pub fn with_dialogue_params(
161 mut self,
162 threshold: f32,
163 min_duration_ms: u64,
164 merge_gap_ms: u64,
165 ) -> Self {
166 self.config.sync.dialogue_detection_threshold = threshold;
167 self.config.sync.min_dialogue_duration_ms = min_duration_ms as u32;
168 self.config.sync.dialogue_merge_gap_ms = merge_gap_ms as u32;
169 self
170 }
171
172 pub fn with_auto_detect_sample_rate(mut self, enabled: bool) -> Self {
178 self.config.sync.auto_detect_sample_rate = enabled;
179 self
180 }
181
182 pub fn with_default_output_format(mut self, format: &str) -> Self {
190 self.config.formats.default_output = format.to_string();
191 self
192 }
193
194 pub fn with_preserve_styling(mut self, preserve: bool) -> Self {
200 self.config.formats.preserve_styling = preserve;
201 self
202 }
203
204 pub fn with_default_encoding(mut self, encoding: &str) -> Self {
210 self.config.formats.default_encoding = encoding.to_string();
211 self
212 }
213
214 pub fn with_encoding_detection_confidence(mut self, confidence: f32) -> Self {
220 self.config.formats.encoding_detection_confidence = confidence;
221 self
222 }
223
224 pub fn with_backup_enabled(mut self, enabled: bool) -> Self {
232 self.config.general.backup_enabled = enabled;
233 self
234 }
235
236 pub fn with_max_concurrent_jobs(mut self, jobs: usize) -> Self {
242 self.config.general.max_concurrent_jobs = jobs;
243 self
244 }
245
246 pub fn with_task_timeout(mut self, timeout_seconds: u64) -> Self {
252 self.config.general.task_timeout_seconds = timeout_seconds;
253 self
254 }
255
256 pub fn with_progress_bar(mut self, enabled: bool) -> Self {
262 self.config.general.enable_progress_bar = enabled;
263 self
264 }
265
266 pub fn with_worker_idle_timeout(mut self, timeout_seconds: u64) -> Self {
272 self.config.general.worker_idle_timeout_seconds = timeout_seconds;
273 self
274 }
275
276 pub fn with_task_queue_size(mut self, size: usize) -> Self {
284 self.config.parallel.task_queue_size = size;
285 self
286 }
287
288 pub fn with_task_priorities(mut self, enabled: bool) -> Self {
294 self.config.parallel.enable_task_priorities = enabled;
295 self
296 }
297
298 pub fn with_auto_balance_workers(mut self, enabled: bool) -> Self {
304 self.config.parallel.auto_balance_workers = enabled;
305 self
306 }
307
308 pub fn with_queue_overflow_strategy(mut self, strategy: OverflowStrategy) -> Self {
314 self.config.parallel.overflow_strategy = strategy;
315 self
316 }
317
318 pub fn with_parallel_settings(mut self, max_workers: usize, queue_size: usize) -> Self {
320 self.config.general.max_concurrent_jobs = max_workers;
321 self.config.parallel.task_queue_size = queue_size;
322 self
323 }
324
325 pub fn build_service(self) -> TestConfigService {
329 TestConfigService::new(self.config)
330 }
331
332 pub fn build_config(self) -> Config {
334 self.config
335 }
336
337 pub fn config(&self) -> &Config {
339 &self.config
340 }
341
342 pub fn config_mut(&mut self) -> &mut Config {
344 &mut self.config
345 }
346 pub fn with_mock_ai_server(mut self, mock_url: &str) -> Self {
348 self.config.ai.base_url = mock_url.to_string();
349 self.config.ai.api_key = Some("mock-api-key".to_string());
350 self
351 }
352}
353
354impl Default for TestConfigBuilder {
355 fn default() -> Self {
356 Self::new()
357 }
358}
359
360#[cfg(test)]
361mod tests {
362 use super::*;
363 use crate::config::service::ConfigService;
364
365 #[test]
366 fn test_builder_default() {
367 let config = TestConfigBuilder::new().build_config();
368 let default_config = Config::default();
369
370 assert_eq!(config.ai.provider, default_config.ai.provider);
371 assert_eq!(config.ai.model, default_config.ai.model);
372 }
373
374 #[test]
375 fn test_builder_ai_configuration() {
376 let config = TestConfigBuilder::new()
377 .with_ai_provider("anthropic")
378 .with_ai_model("claude-3")
379 .with_ai_api_key("test-key")
380 .with_max_sample_length(5000)
381 .with_ai_temperature(0.7)
382 .build_config();
383
384 assert_eq!(config.ai.provider, "anthropic");
385 assert_eq!(config.ai.model, "claude-3");
386 assert_eq!(config.ai.api_key, Some("test-key".to_string()));
387 assert_eq!(config.ai.max_sample_length, 5000);
388 assert_eq!(config.ai.temperature, 0.7);
389 }
390
391 #[test]
392 fn test_builder_sync_configuration() {
393 let config = TestConfigBuilder::new()
394 .with_sync_threshold(0.9)
395 .with_max_offset(60.0)
396 .with_audio_sample_rate(48000)
397 .with_dialogue_detection(false)
398 .build_config();
399
400 assert_eq!(config.sync.correlation_threshold, 0.9);
401 assert_eq!(config.sync.max_offset_seconds, 60.0);
402 assert_eq!(config.sync.audio_sample_rate, 48000);
403 assert!(!config.sync.enable_dialogue_detection);
404 }
405
406 #[test]
407 fn test_builder_service_creation() {
408 let service = TestConfigBuilder::new()
409 .with_ai_provider("test-provider")
410 .build_service();
411
412 let config = service.get_config().unwrap();
413 assert_eq!(config.ai.provider, "test-provider");
414 }
415
416 #[test]
417 fn test_builder_chaining() {
418 let config = TestConfigBuilder::new()
419 .with_ai_provider("openai")
420 .with_ai_model("gpt-4.1")
421 .with_sync_threshold(0.8)
422 .with_max_concurrent_jobs(8)
423 .with_task_queue_size(200)
424 .build_config();
425
426 assert_eq!(config.ai.provider, "openai");
427 assert_eq!(config.ai.model, "gpt-4.1");
428 assert_eq!(config.sync.correlation_threshold, 0.8);
429 assert_eq!(config.general.max_concurrent_jobs, 8);
430 assert_eq!(config.parallel.task_queue_size, 200);
431 }
432}