1use crate::markdown::MarkdownParser;
2use crate::types::Violation;
3use serde_json::Value;
4use std::collections::HashMap;
5
6pub trait Rule: Send + Sync {
7 fn name(&self) -> &str;
8 fn description(&self) -> &str;
9 fn tags(&self) -> &[&str];
10
11 fn check(&self, parser: &MarkdownParser, config: Option<&Value>) -> Vec<Violation>;
13
14 fn fixable(&self) -> bool {
16 false
17 }
18}
19
20#[derive(Default)]
21pub struct RuleRegistry {
22 rules: HashMap<String, Box<dyn Rule + Send + Sync>>,
23}
24
25impl RuleRegistry {
26 #[must_use]
27 pub fn new() -> Self {
28 Self::default()
29 }
30
31 pub fn register(&mut self, rule: Box<dyn Rule + Send + Sync>) {
32 self.rules.insert(rule.name().to_owned(), rule);
33 }
34
35 #[must_use]
36 pub fn get(&self, name: &str) -> Option<&dyn Rule> {
37 self.rules.get(name).map(|r| r.as_ref() as &dyn Rule)
38 }
39
40 pub fn all_rules(&self) -> impl Iterator<Item = &dyn Rule> {
41 self.rules.values().map(|r| r.as_ref() as &dyn Rule)
42 }
43}