use crate::errors::Result;
use crate::tensor::Tensor;
use serde::{Deserialize, Serialize};
use std::any::Any;
use std::collections::HashMap;
pub trait Plugin: Send + Sync + ClonePlugin + std::fmt::Debug {
fn name(&self) -> &str;
fn version(&self) -> &str;
fn description(&self) -> &str;
fn configure(&mut self, config: HashMap<String, serde_json::Value>) -> Result<()>;
fn get_config(&self) -> &HashMap<String, serde_json::Value>;
fn validate_config(&self) -> Result<()> {
Ok(())
}
fn initialize(&mut self) -> Result<()> {
self.validate_config()
}
fn cleanup(&mut self) -> Result<()> {
Ok(())
}
fn as_any(&self) -> &dyn Any;
fn dependencies(&self) -> Vec<String> {
Vec::new()
}
fn capabilities(&self) -> Vec<String> {
Vec::new()
}
fn tags(&self) -> Vec<String> {
Vec::new()
}
fn forward(&self, input: Tensor) -> Result<Tensor>;
}
pub trait ClonePlugin {
fn clone_plugin(&self) -> Box<dyn Plugin>;
}
impl<T> ClonePlugin for T
where
T: Plugin + Clone + 'static,
{
fn clone_plugin(&self) -> Box<dyn Plugin> {
Box::new(self.clone())
}
}
impl Clone for Box<dyn Plugin> {
fn clone(&self) -> Self {
self.clone_plugin()
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum PluginEvent {
Loading { name: String, version: String },
Loaded { name: String, version: String },
Configuring {
name: String,
config: HashMap<String, serde_json::Value>,
},
Initializing { name: String },
Initialized { name: String },
Unloading { name: String },
Unloaded { name: String },
Error { name: String, error: String },
}
pub trait PluginEventHandler: Send + Sync {
fn handle_event(&self, event: &PluginEvent) -> Result<()>;
}
#[derive(Debug)]
pub struct PluginContext {
pub name: String,
pub config: HashMap<String, serde_json::Value>,
pub resources: HashMap<String, Box<dyn Any + Send + Sync>>,
pub metrics: HashMap<String, f64>,
}
impl PluginContext {
pub fn new(name: String, config: HashMap<String, serde_json::Value>) -> Self {
Self {
name,
config,
resources: HashMap::new(),
metrics: HashMap::new(),
}
}
pub fn add_resource<T: Any + Send + Sync>(&mut self, key: String, resource: T) {
self.resources.insert(key, Box::new(resource));
}
pub fn get_resource<T: Any + Send + Sync>(&self, key: &str) -> Option<&T> {
self.resources.get(key).and_then(|r| r.downcast_ref::<T>())
}
pub fn update_metric(&mut self, key: String, value: f64) {
self.metrics.insert(key, value);
}
pub fn get_metric(&self, key: &str) -> Option<f64> {
self.metrics.get(key).copied()
}
}