use std::path::Path;
pub trait MemoryPlugin: Send + Sync {
fn name(&self) -> &str;
fn version(&self) -> &str {
"unknown"
}
fn on_init(&self) -> Result<(), String> {
Ok(())
}
fn on_shutdown(&self) {}
}
#[derive(Default)]
pub struct PluginRegistry {
plugins: Vec<Box<dyn MemoryPlugin>>,
}
impl PluginRegistry {
pub fn empty() -> Self {
Self::default()
}
pub fn load_from_dir(_dir: &Path) -> Self {
Self::empty()
}
pub fn len(&self) -> usize {
self.plugins.len()
}
pub fn is_empty(&self) -> bool {
self.plugins.is_empty()
}
pub fn names(&self) -> impl Iterator<Item = &str> {
self.plugins.iter().map(|p| p.name())
}
}
impl Drop for PluginRegistry {
fn drop(&mut self) {
for plugin in &self.plugins {
plugin.on_shutdown();
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn empty_registry_should_have_zero_plugins() {
let registry = PluginRegistry::empty();
assert_eq!(registry.len(), 0);
assert!(registry.is_empty());
assert_eq!(registry.names().count(), 0);
}
#[test]
fn load_from_dir_should_return_empty_in_oss_build() {
let registry = PluginRegistry::load_from_dir(Path::new("/nonexistent"));
assert!(registry.is_empty());
}
}