#![cfg_attr(coverage_nightly, coverage(off))]
pub mod analyzer;
pub mod orchestrator;
pub mod transformer;
pub mod validator;
use async_trait::async_trait;
use std::sync::Arc;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum ModuleError {
#[error("Module not found: {0}")]
NotFound(String),
#[error("Module initialization failed: {0}")]
InitFailed(String),
#[error("Module execution failed: {0}")]
ExecutionFailed(String),
}
#[async_trait]
pub trait PmatModule: Send + Sync + 'static {
type Input: Send + Sync;
type Output: Send + Sync;
fn name(&self) -> &'static str;
async fn initialize(&mut self) -> Result<(), ModuleError>;
async fn process(&self, input: Self::Input) -> Result<Self::Output, ModuleError>;
async fn shutdown(&mut self) -> Result<(), ModuleError>;
}
pub struct ModuleRegistry {
modules: dashmap::DashMap<String, Arc<dyn std::any::Any + Send + Sync>>,
}
impl Default for ModuleRegistry {
fn default() -> Self {
Self::new()
}
}
impl ModuleRegistry {
pub fn new() -> Self {
Self {
modules: dashmap::DashMap::new(),
}
}
pub fn register<T>(&self, name: String, module: Arc<T>)
where
T: std::any::Any + Send + Sync + 'static,
{
self.modules
.insert(name, module as Arc<dyn std::any::Any + Send + Sync>);
}
pub fn get<T>(&self, name: &str) -> Option<Arc<T>>
where
T: std::any::Any + Send + Sync + 'static,
{
self.modules
.get(name)
.and_then(|module| module.clone().downcast::<T>().ok())
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_module_registry() {
let registry = ModuleRegistry::new();
#[derive(Debug)]
struct TestModule {
value: i32,
}
let module = Arc::new(TestModule { value: 42 });
registry.register("test".to_string(), module.clone());
let retrieved = registry.get::<TestModule>("test");
assert!(retrieved.is_some());
assert_eq!(retrieved.unwrap().value, 42);
}
}