Skip to main content

perspt_core/plugin/
registry.rs

1use super::*;
2
3/// Plugin registry for dynamic language detection
4pub struct PluginRegistry {
5    plugins: Vec<Box<dyn LanguagePlugin>>,
6}
7
8impl PluginRegistry {
9    /// Create a new registry with all built-in plugins
10    pub fn new() -> Self {
11        Self {
12            plugins: vec![
13                Box::new(RustPlugin),
14                Box::new(PythonPlugin),
15                Box::new(JsPlugin),
16            ],
17        }
18    }
19
20    /// An empty registry, for embedders that assemble their own plugin set.
21    pub fn empty() -> Self {
22        Self {
23            plugins: Vec::new(),
24        }
25    }
26
27    /// Register an additional language plugin. Detection order is
28    /// registration order; built-ins come first in [`Self::new`].
29    pub fn register(&mut self, plugin: Box<dyn LanguagePlugin>) {
30        self.plugins.push(plugin);
31    }
32
33    /// Detect which plugin should handle the given path (first match)
34    pub fn detect(&self, path: &Path) -> Option<&dyn LanguagePlugin> {
35        self.plugins
36            .iter()
37            .find(|p| p.detect(path))
38            .map(|p| p.as_ref())
39    }
40
41    /// PSP-5: Detect ALL plugins that match the given path (polyglot support)
42    ///
43    /// Returns all matching plugins instead of just the first, enabling
44    /// multi-language verification in polyglot repositories.
45    pub fn detect_all(&self, path: &Path) -> Vec<&dyn LanguagePlugin> {
46        self.plugins
47            .iter()
48            .filter(|p| p.detect(path))
49            .map(|p| p.as_ref())
50            .collect()
51    }
52
53    /// Get a plugin by name
54    pub fn get(&self, name: &str) -> Option<&dyn LanguagePlugin> {
55        self.plugins
56            .iter()
57            .find(|p| p.name() == name)
58            .map(|p| p.as_ref())
59    }
60
61    /// Get all registered plugins
62    pub fn all(&self) -> &[Box<dyn LanguagePlugin>] {
63        &self.plugins
64    }
65}
66
67impl Default for PluginRegistry {
68    fn default() -> Self {
69        Self::new()
70    }
71}