use std::collections::HashMap;
use std::sync::Arc;
use crate::acg::error::{AcgError, Result};
use crate::acg::plugin::ProviderPlugin;
pub struct PluginRegistry {
plugins: HashMap<String, Arc<dyn ProviderPlugin>>,
}
impl PluginRegistry {
pub fn new() -> Self {
Self {
plugins: HashMap::new(),
}
}
pub fn register(&mut self, plugin: Arc<dyn ProviderPlugin>) -> Result<()> {
let id = plugin.plugin_id().to_string();
if self.plugins.contains_key(&id) {
return Err(AcgError::PluginAlreadyRegistered(id));
}
self.plugins.insert(id, plugin);
Ok(())
}
pub fn get(&self, plugin_id: &str) -> Option<Arc<dyn ProviderPlugin>> {
self.plugins.get(plugin_id).cloned()
}
pub fn list_plugin_ids(&self) -> Vec<String> {
let mut ids: Vec<String> = self.plugins.keys().cloned().collect();
ids.sort();
ids
}
pub fn deregister(&mut self, plugin_id: &str) -> bool {
self.plugins.remove(plugin_id).is_some()
}
pub fn len(&self) -> usize {
self.plugins.len()
}
pub fn is_empty(&self) -> bool {
self.plugins.is_empty()
}
}
impl Default for PluginRegistry {
fn default() -> Self {
Self::new()
}
}
impl std::fmt::Debug for PluginRegistry {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("PluginRegistry")
.field("plugin_ids", &self.list_plugin_ids())
.finish()
}
}
#[cfg(test)]
#[path = "../../tests/unit/acg/plugin_registry_tests.rs"]
mod tests;