1use corpora_core::subscriber::ek;
5use corpora_core::{Context, Diagnostic, Event, Graph, Interest, RevisionOracle, Subscriber};
6
7pub mod e3;
8pub mod gate_b;
9pub mod held;
10pub mod positional;
11pub mod schema;
12pub mod supersession;
13
14pub use e3::E3;
15pub use gate_b::GateB;
16pub use held::HeldDecision;
17pub use positional::PositionalRef;
18pub use schema::Schema;
19pub use supersession::SupersessionIntegrity;
20
21pub trait Rule {
22 fn code(&self) -> &'static str;
23 fn check(&self, g: &Graph, out: &mut Vec<Diagnostic>);
24}
25
26pub struct RuleRunner {
27 rules: Vec<Box<dyn Rule>>,
28}
29
30impl RuleRunner {
31 pub fn with(rules: Vec<Box<dyn Rule>>) -> Self {
32 RuleRunner { rules }
33 }
34}
35
36impl Subscriber for RuleRunner {
37 fn name(&self) -> &'static str {
38 "rules"
39 }
40
41 fn interest(&self) -> Interest {
42 Interest::only(ek::GRAPH_BUILT)
43 }
44
45 fn handle(&mut self, ev: &Event, cx: &mut Context<'_>) {
46 if let Event::GraphBuilt(g) = ev {
47 let mut ds = Vec::new();
48 for r in &self.rules {
49 r.check(g, &mut ds);
50 }
51 for d in ds {
52 cx.error(d);
53 }
54 }
55 }
56}
57
58pub fn default_rules(oracle: Box<dyn RevisionOracle>) -> Vec<Box<dyn Rule>> {
61 vec![
62 Box::new(Schema),
63 Box::new(SupersessionIntegrity),
64 Box::new(E3),
65 Box::new(HeldDecision),
66 Box::new(PositionalRef),
67 Box::new(GateB::new(oracle)),
68 ]
69}