Skip to main content

graphos_adapters/plugins/
registry.rs

1//! Plugin registry.
2
3use super::{Algorithm, Plugin};
4use graphos_common::utils::error::Result;
5use parking_lot::RwLock;
6use std::collections::HashMap;
7use std::sync::Arc;
8
9/// Registry for managing plugins and algorithms.
10pub struct PluginRegistry {
11    /// Loaded plugins.
12    plugins: RwLock<HashMap<String, Arc<dyn Plugin>>>,
13    /// Registered algorithms.
14    algorithms: RwLock<HashMap<String, Arc<dyn Algorithm>>>,
15}
16
17impl PluginRegistry {
18    /// Creates a new empty registry.
19    pub fn new() -> Self {
20        Self {
21            plugins: RwLock::new(HashMap::new()),
22            algorithms: RwLock::new(HashMap::new()),
23        }
24    }
25
26    /// Registers a plugin.
27    pub fn register_plugin(&self, plugin: Arc<dyn Plugin>) -> Result<()> {
28        plugin.on_load()?;
29        self.plugins.write().insert(plugin.name().to_string(), plugin);
30        Ok(())
31    }
32
33    /// Unregisters a plugin.
34    pub fn unregister_plugin(&self, name: &str) -> Result<()> {
35        if let Some(plugin) = self.plugins.write().remove(name) {
36            plugin.on_unload()?;
37        }
38        Ok(())
39    }
40
41    /// Gets a plugin by name.
42    pub fn get_plugin(&self, name: &str) -> Option<Arc<dyn Plugin>> {
43        self.plugins.read().get(name).cloned()
44    }
45
46    /// Registers an algorithm.
47    pub fn register_algorithm(&self, algorithm: Arc<dyn Algorithm>) {
48        self.algorithms.write().insert(algorithm.name().to_string(), algorithm);
49    }
50
51    /// Gets an algorithm by name.
52    pub fn get_algorithm(&self, name: &str) -> Option<Arc<dyn Algorithm>> {
53        self.algorithms.read().get(name).cloned()
54    }
55
56    /// Lists all registered plugins.
57    pub fn list_plugins(&self) -> Vec<String> {
58        self.plugins.read().keys().cloned().collect()
59    }
60
61    /// Lists all registered algorithms.
62    pub fn list_algorithms(&self) -> Vec<String> {
63        self.algorithms.read().keys().cloned().collect()
64    }
65}
66
67impl Default for PluginRegistry {
68    fn default() -> Self {
69        Self::new()
70    }
71}
72
73#[cfg(test)]
74mod tests {
75    use super::*;
76
77    struct TestPlugin;
78
79    impl Plugin for TestPlugin {
80        fn name(&self) -> &str {
81            "test"
82        }
83
84        fn version(&self) -> &str {
85            "1.0.0"
86        }
87    }
88
89    #[test]
90    fn test_plugin_registration() {
91        let registry = PluginRegistry::new();
92
93        let plugin = Arc::new(TestPlugin);
94        registry.register_plugin(plugin).unwrap();
95
96        assert!(registry.get_plugin("test").is_some());
97        assert_eq!(registry.list_plugins(), vec!["test"]);
98    }
99
100    #[test]
101    fn test_plugin_unregistration() {
102        let registry = PluginRegistry::new();
103
104        let plugin = Arc::new(TestPlugin);
105        registry.register_plugin(plugin).unwrap();
106
107        registry.unregister_plugin("test").unwrap();
108        assert!(registry.get_plugin("test").is_none());
109    }
110}