use super::r#trait::Validator;
use std::sync::Arc;
pub fn register_validator(validator: Arc<dyn Validator>) -> crate::Result<()> {
use crate::plugins::registry::get_validator_registry;
let registry = get_validator_registry();
let mut registry = registry
.write()
.expect("~keep Failed to acquire write lock on validator registry");
registry.register(validator)
}
pub fn unregister_validator(name: &str) -> crate::Result<()> {
use crate::plugins::registry::get_validator_registry;
let registry = get_validator_registry();
let mut registry = registry
.write()
.expect("~keep Failed to acquire write lock on validator registry");
registry.remove(name)
}
pub fn list_validators() -> crate::Result<Vec<String>> {
use crate::plugins::registry::get_validator_registry;
let registry = get_validator_registry();
let registry = registry
.read()
.expect("~keep Failed to acquire read lock on validator registry");
Ok(registry.list())
}
pub fn clear_validators() -> crate::Result<()> {
use crate::plugins::registry::get_validator_registry;
let registry = get_validator_registry();
let mut registry = registry
.write()
.expect("~keep Failed to acquire write lock on validator registry");
registry.shutdown_all()
}
#[cfg(test)]
mod tests {
use super::*;
use crate::KreuzbergError;
use crate::Result;
use crate::core::config::ExtractionConfig;
use crate::plugins::Plugin;
use crate::types::ExtractionResult;
use async_trait::async_trait;
struct MockValidator {
should_fail: bool,
}
impl Plugin for MockValidator {
fn name(&self) -> &str {
"mock-validator"
}
fn version(&self) -> String {
"1.0.0".to_string()
}
fn initialize(&self) -> Result<()> {
Ok(())
}
fn shutdown(&self) -> Result<()> {
Ok(())
}
}
#[async_trait]
impl Validator for MockValidator {
async fn validate(&self, _result: &ExtractionResult, _config: &ExtractionConfig) -> Result<()> {
if self.should_fail {
Err(KreuzbergError::validation("Validation failed".to_string()))
} else {
Ok(())
}
}
}
#[test]
#[serial_test::serial]
fn test_register_validator() {
use std::sync::Arc;
let validator = Arc::new(MockValidator { should_fail: false });
let result = super::register_validator(validator);
assert!(result.is_ok());
let _ = super::unregister_validator("mock-validator");
}
#[test]
#[serial_test::serial]
fn test_unregister_validator() {
use std::sync::Arc;
let validator = Arc::new(MockValidator { should_fail: false });
super::register_validator(validator).unwrap();
let result = super::unregister_validator("mock-validator");
assert!(result.is_ok());
}
#[test]
#[serial_test::serial]
fn test_unregister_nonexistent_validator() {
let result = super::unregister_validator("nonexistent-validator-xyz");
assert!(result.is_ok());
}
#[test]
#[serial_test::serial]
fn test_list_validators() {
use std::sync::Arc;
super::clear_validators().unwrap();
let validator1 = Arc::new(MockValidator { should_fail: false });
let validator2 = Arc::new(MockValidator { should_fail: false });
let list_before = super::list_validators().unwrap();
assert_eq!(list_before.len(), 0);
super::register_validator(validator1).unwrap();
super::register_validator(validator2).unwrap();
let list = super::list_validators().unwrap();
assert_eq!(list.len(), 1);
assert!(list.contains(&"mock-validator".to_string()));
super::unregister_validator("mock-validator").unwrap();
}
#[test]
#[serial_test::serial]
fn test_clear_validators() {
use std::sync::Arc;
super::clear_validators().unwrap();
let validator1 = Arc::new(MockValidator { should_fail: false });
let validator2 = Arc::new(MockValidator { should_fail: false });
super::register_validator(validator1).unwrap();
super::register_validator(validator2).unwrap();
let list_before = super::list_validators().unwrap();
assert!(!list_before.is_empty());
let result = super::clear_validators();
assert!(result.is_ok());
let list = super::list_validators().unwrap();
assert_eq!(list.len(), 0);
}
#[test]
#[serial_test::serial]
fn test_register_validator_with_invalid_name() {
use std::sync::Arc;
struct InvalidNameValidator;
impl Plugin for InvalidNameValidator {
fn name(&self) -> &str {
"invalid name with spaces"
}
fn version(&self) -> String {
"1.0.0".to_string()
}
fn initialize(&self) -> Result<()> {
Ok(())
}
fn shutdown(&self) -> Result<()> {
Ok(())
}
}
#[async_trait]
impl Validator for InvalidNameValidator {
async fn validate(&self, _: &ExtractionResult, _: &ExtractionConfig) -> Result<()> {
Ok(())
}
}
let validator = Arc::new(InvalidNameValidator);
let result = super::register_validator(validator);
assert!(matches!(result, Err(KreuzbergError::Validation { .. })));
}
#[test]
#[serial_test::serial]
fn test_register_validator_with_empty_name() {
use std::sync::Arc;
struct EmptyNameValidator;
impl Plugin for EmptyNameValidator {
fn name(&self) -> &str {
""
}
fn version(&self) -> String {
"1.0.0".to_string()
}
fn initialize(&self) -> Result<()> {
Ok(())
}
fn shutdown(&self) -> Result<()> {
Ok(())
}
}
#[async_trait]
impl Validator for EmptyNameValidator {
async fn validate(&self, _: &ExtractionResult, _: &ExtractionConfig) -> Result<()> {
Ok(())
}
}
let validator = Arc::new(EmptyNameValidator);
let result = super::register_validator(validator);
assert!(matches!(result, Err(KreuzbergError::Validation { .. })));
}
}