use std::collections::HashMap;
use crate::error::{Error, Result};
use crate::language::Language;
use crate::text::TextStatistics;
use super::impls::*;
use super::{Formula, FormulaResult};
pub struct FormulaRegistry {
formulas: Vec<Box<dyn Formula>>,
index: HashMap<String, usize>,
}
impl FormulaRegistry {
pub fn new() -> Self {
FormulaRegistry {
formulas: Vec::new(),
index: HashMap::new(),
}
}
pub fn register(&mut self, formula: Box<dyn Formula>) {
let name = formula.name().to_string();
if let Some(&i) = self.index.get(&name) {
self.formulas[i] = formula;
} else {
self.index.insert(name, self.formulas.len());
self.formulas.push(formula);
}
}
pub fn has(&self, name: &str) -> bool {
self.index.contains_key(name)
}
pub fn get(&self, name: &str) -> Option<&dyn Formula> {
self.index.get(name).map(|&i| self.formulas[i].as_ref())
}
pub fn list_names(&self) -> Vec<String> {
self.formulas.iter().map(|f| f.name().to_string()).collect()
}
pub fn list_for_language(&self, language: &Language) -> Vec<String> {
self.formulas
.iter()
.filter(|f| is_supported(f.as_ref(), language))
.map(|f| f.name().to_string())
.collect()
}
pub fn calculate(
&self,
name: &str,
language: &Language,
stats: &TextStatistics,
) -> Result<FormulaResult> {
match self.get(name) {
Some(f) if is_supported(f, language) => Ok(f.calculate(stats, language)),
_ => Err(Error::UnsupportedFormula {
formula: name.to_string(),
language: language.code.clone(),
}),
}
}
}
impl Default for FormulaRegistry {
fn default() -> Self {
Self::new()
}
}
fn is_supported(formula: &dyn Formula, language: &Language) -> bool {
let langs = formula.supported_languages();
langs == ["*"] || langs.contains(&language.code.as_str())
}
pub fn create() -> FormulaRegistry {
let mut registry = FormulaRegistry::new();
registry.register(Box::new(AutomatedReadabilityIndex));
registry.register(Box::new(ColemanLiau));
registry.register(Box::new(Crawford));
registry.register(Box::new(DaleChall));
registry.register(Box::new(FernandezHuerta));
registry.register(Box::new(FleschKincaidGradeLevel));
registry.register(Box::new(FleschReadingEase));
registry.register(Box::new(FogPL));
registry.register(Box::new(Gulpease));
registry.register(Box::new(GunningFog));
registry.register(Box::new(GutierrezPolini));
registry.register(Box::new(Lix));
registry.register(Box::new(Osman));
registry.register(Box::new(SmogIndex));
registry.register(Box::new(Spache));
registry.register(Box::new(SzigrisztPazos));
registry.register(Box::new(WienerSachtextformel));
registry
}