use std::any::Any;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use crate::{
Error,
buffer::Buffer,
input::Input,
output::Output,
processor::Processor,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum PluginType {
Input,
Output,
Processor,
Buffer,
}
pub struct PluginRegistry {
inputs: Mutex<HashMap<String, Box<dyn Fn() -> Box<dyn Input> + Send + Sync>>>,
outputs: Mutex<HashMap<String, Box<dyn Fn() -> Box<dyn Output> + Send + Sync>>>,
processors: Mutex<HashMap<String, Box<dyn Fn() -> Box<dyn Processor> + Send + Sync>>>,
buffers: Mutex<HashMap<String, Box<dyn Fn() -> Box<dyn Buffer> + Send + Sync>>>,
}
impl PluginRegistry {
pub fn new() -> Self {
Self {
inputs: Mutex::new(HashMap::new()),
outputs: Mutex::new(HashMap::new()),
processors: Mutex::new(HashMap::new()),
buffers: Mutex::new(HashMap::new()),
}
}
pub fn register_input<F>(&self, name: &str, factory: F) -> Result<(), Error>
where
F: Fn() -> Box<dyn Input> + Send + Sync + 'static,
{
let mut inputs = self.inputs.lock().map_err(|e| Error::Unknown(e.to_string()))?;
if inputs.contains_key(name) {
return Err(Error::Config(format!("输入插件 '{}' 已存在", name)));
}
inputs.insert(name.to_string(), Box::new(factory));
Ok(())
}
pub fn register_output<F>(&self, name: &str, factory: F) -> Result<(), Error>
where
F: Fn() -> Box<dyn Output> + Send + Sync + 'static,
{
let mut outputs = self.outputs.lock().map_err(|e| Error::Unknown(e.to_string()))?;
if outputs.contains_key(name) {
return Err(Error::Config(format!("输出插件 '{}' 已存在", name)));
}
outputs.insert(name.to_string(), Box::new(factory));
Ok(())
}
pub fn register_processor<F>(&self, name: &str, factory: F) -> Result<(), Error>
where
F: Fn() -> Box<dyn Processor> + Send + Sync + 'static,
{
let mut processors = self.processors.lock().map_err(|e| Error::Unknown(e.to_string()))?;
if processors.contains_key(name) {
return Err(Error::Config(format!("处理器插件 '{}' 已存在", name)));
}
processors.insert(name.to_string(), Box::new(factory));
Ok(())
}
pub fn register_buffer<F>(&self, name: &str, factory: F) -> Result<(), Error>
where
F: Fn() -> Box<dyn Buffer> + Send + Sync + 'static,
{
let mut buffers = self.buffers.lock().map_err(|e| Error::Unknown(e.to_string()))?;
if buffers.contains_key(name) {
return Err(Error::Config(format!("缓冲区插件 '{}' 已存在", name)));
}
buffers.insert(name.to_string(), Box::new(factory));
Ok(())
}
pub fn create_input(&self, name: &str) -> Result<Box<dyn Input>, Error> {
let inputs = self.inputs.lock().map_err(|e| Error::Unknown(e.to_string()))?;
if let Some(factory) = inputs.get(name) {
Ok(factory())
} else {
Err(Error::Config(format!("输入插件 '{}' 不存在", name)))
}
}
pub fn create_output(&self, name: &str) -> Result<Box<dyn Output>, Error> {
let outputs = self.outputs.lock().map_err(|e| Error::Unknown(e.to_string()))?;
if let Some(factory) = outputs.get(name) {
Ok(factory())
} else {
Err(Error::Config(format!("输出插件 '{}' 不存在", name)))
}
}
pub fn create_processor(&self, name: &str) -> Result<Box<dyn Processor>, Error> {
let processors = self.processors.lock().map_err(|e| Error::Unknown(e.to_string()))?;
if let Some(factory) = processors.get(name) {
Ok(factory())
} else {
Err(Error::Config(format!("处理器插件 '{}' 不存在", name)))
}
}
pub fn create_buffer(&self, name: &str) -> Result<Box<dyn Buffer>, Error> {
let buffers = self.buffers.lock().map_err(|e| Error::Unknown(e.to_string()))?;
if let Some(factory) = buffers.get(name) {
Ok(factory())
} else {
Err(Error::Config(format!("缓冲区插件 '{}' 不存在", name)))
}
}
pub fn list_plugins(&self) -> Result<HashMap<PluginType, Vec<String>>, Error> {
let mut result = HashMap::new();
let inputs = self.inputs.lock().map_err(|e| Error::Unknown(e.to_string()))?;
result.insert(PluginType::Input, inputs.keys().cloned().collect());
let outputs = self.outputs.lock().map_err(|e| Error::Unknown(e.to_string()))?;
result.insert(PluginType::Output, outputs.keys().cloned().collect());
let processors = self.processors.lock().map_err(|e| Error::Unknown(e.to_string()))?;
result.insert(PluginType::Processor, processors.keys().cloned().collect());
let buffers = self.buffers.lock().map_err(|e| Error::Unknown(e.to_string()))?;
result.insert(PluginType::Buffer, buffers.keys().cloned().collect());
Ok(result)
}
}
lazy_static::lazy_static! {
static ref GLOBAL_REGISTRY: Arc<PluginRegistry> = Arc::new(PluginRegistry::new());
}
pub fn global_registry() -> Arc<PluginRegistry> {
GLOBAL_REGISTRY.clone()
}
pub trait Plugin: Any + Send + Sync {
fn name(&self) -> &str;
fn plugin_type(&self) -> PluginType;
fn register(&self, registry: &PluginRegistry) -> Result<(), Error>;
}