sakurs_cli/commands/
validate.rs

1//! Validate command implementation
2
3use anyhow::Result;
4use clap::Args;
5use std::path::PathBuf;
6
7/// Arguments for the validate command
8#[derive(Debug, Args)]
9pub struct ValidateArgs {
10    /// Path to language configuration file to validate
11    #[arg(short = 'c', long, value_name = "FILE", required = true)]
12    pub language_config: PathBuf,
13}
14
15impl ValidateArgs {
16    /// Execute the validate command
17    pub fn execute(&self) -> Result<()> {
18        use sakurs_core::domain::language::ConfigurableLanguageRules;
19        use sakurs_core::LanguageRules;
20
21        println!(
22            "Validating language configuration: {}",
23            self.language_config.display()
24        );
25
26        // Try to load and validate the configuration
27        match ConfigurableLanguageRules::from_file(&self.language_config, None) {
28            Ok(rules) => {
29                println!("✓ Configuration is valid!");
30                println!("  Language code: {}", rules.language_code());
31                println!("  Language name: {}", rules.language_name());
32                Ok(())
33            }
34            Err(e) => {
35                println!("✗ Configuration is invalid!");
36                println!("  Error: {e}");
37                Err(anyhow::anyhow!("Validation failed: {}", e))
38            }
39        }
40    }
41}
42
43#[cfg(test)]
44mod tests {
45    use super::*;
46    use std::io::Write;
47    use tempfile::NamedTempFile;
48
49    #[test]
50    fn test_validate_args_debug() {
51        let args = ValidateArgs {
52            language_config: PathBuf::from("test.toml"),
53        };
54
55        let debug_str = format!("{:?}", args);
56        assert!(debug_str.contains("ValidateArgs"));
57        assert!(debug_str.contains("test.toml"));
58    }
59
60    #[test]
61    fn test_validate_valid_config() {
62        let toml_content = r#"
63[metadata]
64code = "test"
65name = "Test Language"
66
67[terminators]
68chars = ["."]
69
70[ellipsis]
71patterns = []
72
73[enclosures]
74pairs = []
75
76[suppression]
77
78[abbreviations]
79
80[sentence_starters]
81common = ["The", "A"]
82"#;
83
84        let mut temp_file = NamedTempFile::new().unwrap();
85        write!(temp_file, "{}", toml_content).unwrap();
86
87        let args = ValidateArgs {
88            language_config: temp_file.path().to_path_buf(),
89        };
90
91        assert!(args.execute().is_ok());
92    }
93
94    #[test]
95    fn test_validate_invalid_config() {
96        let toml_content = r#"
97[metadata]
98code = ""
99name = "Test"
100
101[terminators]
102chars = ["."]
103"#;
104
105        let mut temp_file = NamedTempFile::new().unwrap();
106        write!(temp_file, "{}", toml_content).unwrap();
107
108        let args = ValidateArgs {
109            language_config: temp_file.path().to_path_buf(),
110        };
111
112        assert!(args.execute().is_err());
113    }
114}