use crate::error::Result;
use crate::traits::{Repair, RepairStrategy, Validator};
pub struct GenericRepairer {
strategies: Vec<Box<dyn RepairStrategy>>,
validator: Box<dyn Validator>,
}
impl GenericRepairer {
pub fn new(
validator: Box<dyn Validator>,
mut strategies: Vec<Box<dyn RepairStrategy>>,
) -> Self {
strategies.sort_by_key(|s| std::cmp::Reverse(s.priority()));
Self {
strategies,
validator,
}
}
fn apply_strategies_internal(&mut self, content: &str) -> Result<String> {
let mut repaired = content.to_string();
for strategy in self.strategies.iter() {
if let Ok(result) = strategy.apply(&repaired) {
repaired = result;
}
}
Ok(repaired)
}
pub fn validator(&self) -> &dyn Validator {
self.validator.as_ref()
}
pub fn strategies(&self) -> &[Box<dyn RepairStrategy>] {
&self.strategies
}
}
impl Repair for GenericRepairer {
fn repair(&mut self, content: &str) -> Result<String> {
let trimmed = content.trim();
if trimmed.is_empty() {
return Ok(String::new());
}
if self.validator.is_valid(trimmed) {
return Ok(trimmed.to_string());
}
let repaired = self.apply_strategies_internal(trimmed)?;
Ok(repaired)
}
fn needs_repair(&self, content: &str) -> bool {
!self.validator.is_valid(content)
}
fn confidence(&self, content: &str) -> f64 {
if self.validator.is_valid(content) {
1.0
} else {
0.0
}
}
}