Skip to main content

alint_core/
registry.rs

1use std::collections::HashMap;
2
3use crate::config::RuleSpec;
4use crate::error::{Error, Result};
5use crate::rule::Rule;
6
7pub type RuleBuilder = fn(&RuleSpec) -> Result<Box<dyn Rule>>;
8
9/// Map from `kind` string → factory function. Built-in rule crates register
10/// themselves here at startup, and plugin rules (in later phases) will too.
11#[derive(Default)]
12pub struct RuleRegistry {
13    builders: HashMap<String, RuleBuilder>,
14}
15
16impl std::fmt::Debug for RuleRegistry {
17    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18        f.debug_struct("RuleRegistry")
19            .field("kinds", &self.builders.keys().collect::<Vec<_>>())
20            .finish()
21    }
22}
23
24impl RuleRegistry {
25    pub fn new() -> Self {
26        Self::default()
27    }
28
29    pub fn register(&mut self, kind: &str, builder: RuleBuilder) {
30        self.builders.insert(kind.to_string(), builder);
31    }
32
33    pub fn build(&self, spec: &RuleSpec) -> Result<Box<dyn Rule>> {
34        let builder = self
35            .builders
36            .get(&spec.kind)
37            .ok_or_else(|| Error::UnknownRuleKind(spec.kind.clone()))?;
38        builder(spec)
39    }
40
41    pub fn known_kinds(&self) -> impl Iterator<Item = &str> {
42        self.builders.keys().map(String::as_str)
43    }
44}