subx_cli/lib.rs
1//! SubX: Intelligent Subtitle Processing Library
2//!
3//! SubX is a comprehensive Rust library for intelligent subtitle file processing,
4//! featuring AI-powered matching, format conversion, audio synchronization,
5//! and advanced encoding detection capabilities.
6//!
7//! # Key Features
8//!
9//! - **AI-Powered Matching**: Intelligent subtitle file matching and renaming
10//! - **Format Conversion**: Support for multiple subtitle formats (SRT, ASS, VTT, etc.)
11//! - **Audio Synchronization**: Advanced audio-subtitle timing adjustment
12//! - **Encoding Detection**: Automatic character encoding detection and conversion
13//! - **Parallel Processing**: High-performance batch operations
14//! - **Configuration Management**: Flexible multi-source configuration system
15//!
16//! # Architecture Overview
17//!
18//! The library is organized into several key modules:
19//!
20//! - [`cli`] - Command-line interface and argument parsing
21//! - [`commands`] - Implementation of all SubX commands
22//! - [`config`] - Configuration management and validation
23//! - [`core`] - Core processing engines (formats, matching, sync)
24//! - [`error`] - Comprehensive error handling system
25//! - [`services`] - External service integrations (AI, audio processing)
26//!
27//! # Quick Start
28//!
29//! ```rust,no_run
30//! use subx_cli::config::{TestConfigService, ConfigService};
31//!
32//! // Create a configuration service
33//! let config_service = TestConfigService::with_defaults();
34//! let config = config_service.config();
35//!
36//! // Use the configuration for processing...
37//! ```
38//!
39//! # Error Handling
40//!
41//! All operations return a [`Result<T>`] type that wraps [`error::SubXError`]:
42//!
43//! ```rust
44//! use subx_cli::{Result, error::SubXError};
45//!
46//! fn example_operation() -> Result<String> {
47//! // This could fail with various error types
48//! Err(SubXError::config("Missing configuration"))
49//! }
50//! ```
51//!
52//! # Configuration
53//!
54//! SubX supports dependency injection-based configuration:
55//!
56//! ```rust,no_run
57//! use subx_cli::config::{TestConfigService, Config};
58//!
59//! // Create configuration service with AI settings
60//! let config_service = TestConfigService::with_ai_settings("openai", "gpt-4");
61//! let config = config_service.config();
62//!
63//! // Access configuration values
64//! println!("AI Provider: {}", config.ai.provider);
65//! println!("AI Model: {}", config.ai.model);
66//! ```
67//!
68//! # Performance Considerations
69//!
70//! - Use [`core::parallel`] for batch operations on large file sets
71//! - Configure appropriate cache settings for repeated operations
72//! - Consider memory usage when processing large audio files
73//!
74//! # Thread Safety
75//!
76//! The library is designed to be thread-safe where appropriate:
77//! - Configuration manager uses `Arc<RwLock<T>>` for shared state
78//! - File operations include rollback capabilities for atomicity
79//! - Parallel processing uses safe concurrency patterns
80//!
81//! # Feature Flags
82//!
83//! SubX supports several optional features:
84//! ```text
85//! - ai - AI service integrations (default)
86//! - audio - Audio processing capabilities (default)
87//! - parallel - Parallel processing support (default)
88//! ```
89#![allow(
90 clippy::new_without_default,
91 clippy::manual_clamp,
92 clippy::useless_vec,
93 clippy::items_after_test_module,
94 clippy::needless_borrow
95)]
96
97/// Library version string.
98///
99/// This constant provides the current version of the SubX library,
100/// automatically populated from `Cargo.toml` at compile time.
101///
102/// # Examples
103///
104/// ```rust
105/// use subx_cli::VERSION;
106///
107/// println!("SubX version: {}", VERSION);
108/// ```
109pub const VERSION: &str = env!("CARGO_PKG_VERSION");
110
111pub mod cli;
112pub mod commands;
113pub mod config;
114pub use config::Config;
115// Re-export new configuration service system
116pub use config::{
117 ConfigService, EnvironmentProvider, ProductionConfigService, SystemEnvironmentProvider,
118 TestConfigBuilder, TestConfigService, TestEnvironmentProvider,
119};
120pub mod core;
121pub mod error;
122/// Convenient type alias for `Result<T, SubXError>`.
123///
124/// This type alias simplifies error handling throughout the SubX library
125/// by providing a default error type for all fallible operations.
126pub type Result<T> = error::SubXResult<T>;
127
128pub mod services;
129
130/// Main application structure with dependency injection support.
131///
132/// This struct provides the new dependency injection-based architecture
133/// for the SubX application, allowing for better testability and
134/// configuration management.
135pub struct App {
136 config_service: std::sync::Arc<dyn config::ConfigService>,
137}
138
139impl App {
140 /// Create a new application instance with the provided configuration service.
141 ///
142 /// # Arguments
143 ///
144 /// * `config_service` - The configuration service to use
145 pub fn new(config_service: std::sync::Arc<dyn config::ConfigService>) -> Self {
146 Self { config_service }
147 }
148
149 /// Create a new application instance with the production configuration service.
150 ///
151 /// This is the default way to create an application instance for production use.
152 ///
153 /// # Errors
154 ///
155 /// Returns an error if the production configuration service cannot be created.
156 pub fn new_with_production_config() -> Result<Self> {
157 let config_service = std::sync::Arc::new(config::ProductionConfigService::new()?);
158 Ok(Self::new(config_service))
159 }
160
161 /// Run the application with command-line argument parsing.
162 ///
163 /// This method parses command-line arguments and executes the appropriate command
164 /// with the configured dependencies.
165 ///
166 /// # Errors
167 ///
168 /// Returns an error if command execution fails.
169 pub async fn run(&self) -> Result<()> {
170 let cli = <cli::Cli as clap::Parser>::parse();
171 self.handle_command(cli.command).await
172 }
173
174 /// Handle a specific command with the current configuration.
175 ///
176 /// # Arguments
177 ///
178 /// * `command` - The command to execute
179 ///
180 /// # Errors
181 ///
182 /// Returns an error if command execution fails.
183 pub async fn handle_command(&self, command: cli::Commands) -> Result<()> {
184 match command {
185 cli::Commands::Match(args) => {
186 crate::commands::match_command::execute_with_config(
187 args,
188 self.config_service.clone(),
189 )
190 .await
191 }
192 cli::Commands::Convert(args) => {
193 crate::commands::convert_command::execute_with_config(
194 args,
195 self.config_service.clone(),
196 )
197 .await
198 }
199 cli::Commands::Sync(args) => {
200 crate::commands::sync_command::execute_with_config(
201 args,
202 self.config_service.clone(),
203 )
204 .await
205 }
206 cli::Commands::Config(args) => {
207 crate::commands::config_command::execute_with_config(
208 args,
209 self.config_service.clone(),
210 )
211 .await
212 }
213 cli::Commands::GenerateCompletion(args) => {
214 let mut cmd = <cli::Cli as clap::CommandFactory>::command();
215 let cmd_name = cmd.get_name().to_string();
216 let mut stdout = std::io::stdout();
217 clap_complete::generate(args.shell, &mut cmd, cmd_name, &mut stdout);
218 Ok(())
219 }
220 cli::Commands::Cache(args) => {
221 crate::commands::cache_command::execute_with_config(
222 args,
223 self.config_service.clone(),
224 )
225 .await
226 }
227 cli::Commands::DetectEncoding(args) => {
228 crate::commands::detect_encoding_command::detect_encoding_command_with_config(
229 &args.file_paths,
230 args.verbose,
231 self.config_service.clone(),
232 )?;
233 Ok(())
234 }
235 }
236 }
237
238 /// Get a reference to the configuration service.
239 ///
240 /// This allows access to the configuration service for testing or
241 /// advanced use cases.
242 pub fn config_service(&self) -> &std::sync::Arc<dyn config::ConfigService> {
243 &self.config_service
244 }
245
246 /// Get the current configuration.
247 ///
248 /// This is a convenience method that retrieves the configuration
249 /// from the configured service.
250 ///
251 /// # Errors
252 ///
253 /// Returns an error if configuration loading fails.
254 pub fn get_config(&self) -> Result<config::Config> {
255 self.config_service.get_config()
256 }
257}
258
259/// Backward compatibility function that has been replaced by the new CLI interface.
260///
261/// This function has been deprecated. Use `cli::run()` instead.
262#[deprecated(since = "0.2.0", note = "Use cli::run() instead")]
263pub async fn run_with_legacy_config() -> Result<()> {
264 // Use the new CLI interface instead
265 cli::run().await
266}