polykit_core/
adapter_registry.rs

1//! Registry for language adapters to support plugin-like extensibility.
2
3use std::collections::HashMap;
4use std::sync::Mutex;
5
6use crate::adapter::LanguageAdapter;
7use crate::package::Language;
8
9type AdapterFactory = Box<dyn Fn() -> Box<dyn LanguageAdapter> + Send + Sync>;
10
11/// Global registry for language adapters.
12pub struct AdapterRegistry {
13    adapters: Mutex<HashMap<String, AdapterFactory>>,
14}
15
16impl AdapterRegistry {
17    /// Creates a new adapter registry.
18    pub fn new() -> Self {
19        Self {
20            adapters: Mutex::new(HashMap::new()),
21        }
22    }
23
24    /// Registers an adapter factory for a language.
25    ///
26    /// # Arguments
27    ///
28    /// * `language` - The language identifier (e.g., "js", "rust")
29    /// * `factory` - A function that creates an instance of the adapter
30    pub fn register<F>(&self, language: &str, factory: F)
31    where
32        F: Fn() -> Box<dyn LanguageAdapter> + Send + Sync + 'static,
33    {
34        if let Ok(mut adapters) = self.adapters.lock() {
35            adapters.insert(language.to_string(), Box::new(factory));
36        }
37    }
38
39    /// Gets an adapter for a language.
40    ///
41    /// Returns `None` if no adapter is registered for the language.
42    pub fn get(&self, language: &str) -> Option<Box<dyn LanguageAdapter>> {
43        self.adapters
44            .lock()
45            .ok()
46            .and_then(|adapters| adapters.get(language).map(|factory| factory()))
47    }
48
49    /// Gets an adapter for a Language enum.
50    pub fn get_for_language(&self, language: &Language) -> Option<Box<dyn LanguageAdapter>> {
51        self.get(language.as_str())
52    }
53
54    /// Lists all registered languages.
55    pub fn registered_languages(&self) -> Vec<String> {
56        self.adapters
57            .lock()
58            .ok()
59            .map(|adapters| adapters.keys().cloned().collect())
60            .unwrap_or_default()
61    }
62}
63
64impl Default for AdapterRegistry {
65    fn default() -> Self {
66        Self::new()
67    }
68}