ricecoder_refactoring/config/
manager.rs1use crate::error::Result;
4use crate::providers::ProviderRegistry;
5use crate::types::RefactoringConfig;
6use std::collections::HashMap;
7use std::sync::Arc;
8use tokio::sync::RwLock;
9use ricecoder_storage::manager::StorageManager;
10
11pub struct ConfigManager {
13 configs: Arc<RwLock<HashMap<String, RefactoringConfig>>>,
14 provider_registry: Arc<RwLock<Option<ProviderRegistry>>>,
15 storage: Option<Arc<dyn StorageManager>>,
16}
17
18impl ConfigManager {
19 pub fn new() -> Self {
21 Self {
22 configs: Arc::new(RwLock::new(HashMap::new())),
23 provider_registry: Arc::new(RwLock::new(None)),
24 storage: None,
25 }
26 }
27
28 pub fn with_storage(storage: Arc<dyn StorageManager>) -> Self {
30 Self {
31 configs: Arc::new(RwLock::new(HashMap::new())),
32 provider_registry: Arc::new(RwLock::new(None)),
33 storage: Some(storage),
34 }
35 }
36
37 pub fn with_provider_registry(provider_registry: ProviderRegistry) -> Self {
39 Self {
40 configs: Arc::new(RwLock::new(HashMap::new())),
41 provider_registry: Arc::new(RwLock::new(Some(provider_registry))),
42 storage: None,
43 }
44 }
45
46 pub fn with_storage_and_registry(
48 storage: Arc<dyn StorageManager>,
49 provider_registry: ProviderRegistry,
50 ) -> Self {
51 Self {
52 configs: Arc::new(RwLock::new(HashMap::new())),
53 provider_registry: Arc::new(RwLock::new(Some(provider_registry))),
54 storage: Some(storage),
55 }
56 }
57
58 pub fn set_storage(&mut self, storage: Arc<dyn StorageManager>) {
60 self.storage = Some(storage);
61 }
62
63 pub fn get_storage(&self) -> Option<&Arc<dyn StorageManager>> {
65 self.storage.as_ref()
66 }
67
68 pub async fn set_provider_registry(&self, registry: ProviderRegistry) -> Result<()> {
70 let mut provider_registry = self.provider_registry.write().await;
71 *provider_registry = Some(registry);
72 Ok(())
73 }
74
75 pub async fn get_provider_registry(&self) -> Result<Option<ProviderRegistry>> {
77 let provider_registry = self.provider_registry.read().await;
78 Ok(provider_registry.clone())
79 }
80
81 pub async fn register_config(&self, config: RefactoringConfig) -> Result<()> {
83 let mut configs = self.configs.write().await;
84 configs.insert(config.language.clone(), config);
85 Ok(())
86 }
87
88 pub async fn get_config(&self, language: &str) -> Result<Option<RefactoringConfig>> {
93 if let Some(storage) = &self.storage {
95 use crate::config::storage_loader::StorageConfigLoader;
96 let loader = StorageConfigLoader::new(storage.clone());
97
98 if loader.has_language_config(language)? {
100 let config = loader.load_language_config(language)?;
101 let mut configs = self.configs.write().await;
103 configs.insert(language.to_string(), config.clone());
104 return Ok(Some(config));
105 }
106 }
107
108 let configs = self.configs.read().await;
110 Ok(configs.get(language).cloned())
111 }
112
113 pub async fn load_and_register(&self, path: &std::path::Path) -> Result<()> {
115 use crate::config::loader::ConfigLoader;
116
117 let config = ConfigLoader::load(path)?;
118 ConfigLoader::validate(&config)?;
119 self.register_config(config).await?;
120
121 Ok(())
122 }
123
124 pub async fn get_languages(&self) -> Result<Vec<String>> {
129 if let Some(storage) = &self.storage {
131 use crate::config::storage_loader::StorageConfigLoader;
132 let loader = StorageConfigLoader::new(storage.clone());
133 return loader.list_available_languages();
134 }
135
136 let configs = self.configs.read().await;
138 Ok(configs.keys().cloned().collect())
139 }
140
141 pub async fn has_language(&self, language: &str) -> Result<bool> {
146 if let Some(storage) = &self.storage {
148 use crate::config::storage_loader::StorageConfigLoader;
149 let loader = StorageConfigLoader::new(storage.clone());
150 return loader.has_language_config(language);
151 }
152
153 let configs = self.configs.read().await;
155 Ok(configs.contains_key(language))
156 }
157
158 pub async fn clear(&self) -> Result<()> {
160 let mut configs = self.configs.write().await;
161 configs.clear();
162 Ok(())
163 }
164}
165
166impl Default for ConfigManager {
167 fn default() -> Self {
168 Self::new()
169 }
170}
171
172#[cfg(test)]
173mod tests {
174 use super::*;
175
176 #[tokio::test]
177 async fn test_register_and_get_config() -> Result<()> {
178 let manager = ConfigManager::new();
179 let config = RefactoringConfig {
180 language: "rust".to_string(),
181 extensions: vec![".rs".to_string()],
182 rules: vec![],
183 transformations: vec![],
184 provider: None,
185 };
186
187 manager.register_config(config.clone()).await?;
188 let retrieved = manager.get_config("rust").await?;
189
190 assert!(retrieved.is_some());
191 assert_eq!(retrieved.unwrap().language, "rust");
192
193 Ok(())
194 }
195
196 #[tokio::test]
197 async fn test_get_languages() -> Result<()> {
198 let manager = ConfigManager::new();
199
200 let rust_config = RefactoringConfig {
201 language: "rust".to_string(),
202 extensions: vec![".rs".to_string()],
203 rules: vec![],
204 transformations: vec![],
205 provider: None,
206 };
207
208 let ts_config = RefactoringConfig {
209 language: "typescript".to_string(),
210 extensions: vec![".ts".to_string()],
211 rules: vec![],
212 transformations: vec![],
213 provider: None,
214 };
215
216 manager.register_config(rust_config).await?;
217 manager.register_config(ts_config).await?;
218
219 let languages = manager.get_languages().await?;
220 assert_eq!(languages.len(), 2);
221 assert!(languages.contains(&"rust".to_string()));
222 assert!(languages.contains(&"typescript".to_string()));
223
224 Ok(())
225 }
226
227 #[tokio::test]
228 async fn test_has_language() -> Result<()> {
229 let manager = ConfigManager::new();
230 let config = RefactoringConfig {
231 language: "rust".to_string(),
232 extensions: vec![".rs".to_string()],
233 rules: vec![],
234 transformations: vec![],
235 provider: None,
236 };
237
238 manager.register_config(config).await?;
239
240 assert!(manager.has_language("rust").await?);
241 assert!(!manager.has_language("python").await?);
242
243 Ok(())
244 }
245
246 #[tokio::test]
247 async fn test_clear() -> Result<()> {
248 let manager = ConfigManager::new();
249 let config = RefactoringConfig {
250 language: "rust".to_string(),
251 extensions: vec![".rs".to_string()],
252 rules: vec![],
253 transformations: vec![],
254 provider: None,
255 };
256
257 manager.register_config(config).await?;
258 assert!(manager.has_language("rust").await?);
259
260 manager.clear().await?;
261 assert!(!manager.has_language("rust").await?);
262
263 Ok(())
264 }
265}