ricecoder_lsp/config/
loader.rs

1//! Configuration loader for loading language configurations from files
2
3use super::types::{ConfigError, ConfigRegistry, ConfigResult, LanguageConfig};
4use std::path::Path;
5
6/// Configuration loader
7pub struct ConfigLoader;
8
9impl ConfigLoader {
10    /// Load configuration from a YAML file
11    pub fn load_yaml(path: &Path) -> ConfigResult<LanguageConfig> {
12        let content = std::fs::read_to_string(path)?;
13        let config: LanguageConfig = serde_yaml::from_str(&content)?;
14        config.validate()?;
15        Ok(config)
16    }
17
18    /// Load configuration from a JSON file
19    pub fn load_json(path: &Path) -> ConfigResult<LanguageConfig> {
20        let content = std::fs::read_to_string(path)?;
21        let config: LanguageConfig = serde_json::from_str(&content)?;
22        config.validate()?;
23        Ok(config)
24    }
25
26    /// Load configuration from a file (auto-detect format)
27    pub fn load(path: &Path) -> ConfigResult<LanguageConfig> {
28        match path.extension().and_then(|ext| ext.to_str()) {
29            Some("yaml") | Some("yml") => Self::load_yaml(path),
30            Some("json") => Self::load_json(path),
31            _ => Err(ConfigError::ValidationError(
32                "Unsupported configuration file format".to_string(),
33            )),
34        }
35    }
36
37    /// Load all configurations from a directory
38    pub fn load_directory(path: &Path) -> ConfigResult<ConfigRegistry> {
39        let mut registry = ConfigRegistry::new();
40
41        if !path.is_dir() {
42            return Err(ConfigError::ValidationError(format!(
43                "Path is not a directory: {}",
44                path.display()
45            )));
46        }
47
48        for entry in std::fs::read_dir(path)? {
49            let entry = entry?;
50            let path = entry.path();
51
52            if path.is_file() {
53                if let Some(ext) = path.extension().and_then(|e| e.to_str()) {
54                    if ext == "yaml" || ext == "yml" || ext == "json" {
55                        match Self::load(&path) {
56                            Ok(config) => {
57                                registry.register(config)?;
58                            }
59                            Err(e) => {
60                                tracing::warn!(
61                                    "Failed to load configuration from {}: {}",
62                                    path.display(),
63                                    e
64                                );
65                            }
66                        }
67                    }
68                }
69            }
70        }
71
72        Ok(registry)
73    }
74}
75
76#[cfg(test)]
77mod tests {
78    use super::*;
79
80    #[test]
81    fn test_load_unsupported_format() {
82        let result = ConfigLoader::load(Path::new("test.txt"));
83        assert!(result.is_err());
84    }
85}