Skip to main content

corpora_core/
subscriber.rs

1//! The bus contract: every component is a [`Subscriber`] that reacts to [`Event`]s and
2//! emits more through its [`Context`]. [`Interest`] is a cheap bitset prefilter.
3
4use std::collections::VecDeque;
5
6use crate::config::Config;
7use crate::diagnostic::Diagnostic;
8use crate::event::Event;
9
10/// Event-kind bits for [`Interest`] prefiltering.
11pub mod ek {
12    pub const RUN_STARTED: u32 = 1 << 0;
13    pub const DISCOVERED: u32 = 1 << 1;
14    pub const CHANGED: u32 = 1 << 2;
15    pub const REMOVED: u32 = 1 << 3;
16    pub const SETTLED: u32 = 1 << 4;
17    pub const PARSED: u32 = 1 << 5;
18    pub const PARSE_FAILED: u32 = 1 << 6;
19    pub const GRAPH_BUILT: u32 = 1 << 7;
20    pub const DIAGNOSTIC: u32 = 1 << 8;
21    pub const REPORT: u32 = 1 << 9;
22    pub const RUN_FINISHED: u32 = 1 << 10;
23}
24
25fn event_bit(ev: &Event) -> u32 {
26    match ev {
27        Event::RunStarted { .. } => ek::RUN_STARTED,
28        Event::Discovered(_) => ek::DISCOVERED,
29        Event::Changed(_) => ek::CHANGED,
30        Event::Removed(_) => ek::REMOVED,
31        Event::Settled => ek::SETTLED,
32        Event::Parsed(_) => ek::PARSED,
33        Event::ParseFailed { .. } => ek::PARSE_FAILED,
34        Event::GraphBuilt(_) => ek::GRAPH_BUILT,
35        Event::Diagnostic(_) => ek::DIAGNOSTIC,
36        Event::Report(_) => ek::REPORT,
37        Event::RunFinished(_) => ek::RUN_FINISHED,
38    }
39}
40
41#[derive(Clone, Copy, Debug)]
42pub struct Interest(u32);
43
44impl Interest {
45    pub const ALL: Interest = Interest(u32::MAX);
46
47    pub const fn only(bits: u32) -> Interest {
48        Interest(bits)
49    }
50
51    pub fn wants(&self, ev: &Event) -> bool {
52        self.0 & event_bit(ev) != 0
53    }
54}
55
56pub trait Subscriber {
57    fn name(&self) -> &'static str;
58
59    fn interest(&self) -> Interest {
60        Interest::ALL
61    }
62
63    fn handle(&mut self, ev: &Event, cx: &mut Context<'_>);
64}
65
66/// What a subscriber sees on the bus: read config, emit follow-on events.
67pub struct Context<'a> {
68    pub cfg: &'a Config,
69    out: &'a mut VecDeque<Event>,
70}
71
72impl<'a> Context<'a> {
73    pub fn new(cfg: &'a Config, out: &'a mut VecDeque<Event>) -> Self {
74        Context { cfg, out }
75    }
76
77    pub fn emit(&mut self, ev: Event) {
78        self.out.push_back(ev);
79    }
80
81    pub fn error(&mut self, d: Diagnostic) {
82        self.emit(Event::Diagnostic(d));
83    }
84}