use std::sync::Arc;
use cpex_core::{
cmf::CmfHook,
error::PluginError,
factory::{PluginFactory, PluginInstance},
hooks::TypedHandlerAdapter,
plugin::PluginConfig,
};
use crate::scanner::PiiScanner;
pub const KIND: &str = "validator/pii-scan";
pub struct PiiScannerFactory;
impl PluginFactory for PiiScannerFactory {
fn create(&self, config: &PluginConfig) -> Result<PluginInstance, Box<PluginError>> {
let scanner = Arc::new(PiiScanner::new(config.clone())?);
if config.hooks.is_empty() {
return Err(Box::new(PluginError::Config {
message: format!(
"plugin '{}' (cpex-plugin-pii-scanner): `hooks:` must list at \
least one CMF hook to scan on (e.g. cmf.tool_pre_invoke)",
config.name
),
}));
}
let handlers: Vec<_> = config
.hooks
.iter()
.map(|h| -> (&'static str, _) {
let leaked: &'static str = Box::leak(h.clone().into_boxed_str());
let adapter: Arc<dyn cpex_core::registry::AnyHookHandler> =
Arc::new(TypedHandlerAdapter::<CmfHook, _>::new(Arc::clone(&scanner)));
(leaked, adapter)
})
.collect();
Ok(PluginInstance {
plugin: scanner,
handlers,
})
}
}