omena_reactive/
divergence.rs1#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
3#[non_exhaustive]
4pub enum ReactiveDivergenceClassV0 {
5 FlushConeClosureTiming,
6 MidWaveReadTiming,
7}
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10#[non_exhaustive]
11pub enum ReactiveObservationPhaseV0 {
12 DuringWave,
13 Flush,
14}
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
17#[non_exhaustive]
18pub enum ReactiveDivergenceDispositionV0 {
19 BenignUntilFlush,
20 Blocker,
21}
22
23impl ReactiveDivergenceClassV0 {
24 pub const fn all() -> &'static [Self] {
26 &[Self::FlushConeClosureTiming, Self::MidWaveReadTiming]
27 }
28
29 pub const fn id(self) -> &'static str {
30 match self {
31 Self::FlushConeClosureTiming => "flushConeClosureTiming",
32 Self::MidWaveReadTiming => "midWaveReadTiming",
33 }
34 }
35
36 pub fn from_id(id: &str) -> Option<Self> {
37 Self::all().iter().copied().find(|class| class.id() == id)
38 }
39
40 pub const fn disposition(
43 self,
44 phase: ReactiveObservationPhaseV0,
45 ) -> ReactiveDivergenceDispositionV0 {
46 match phase {
47 ReactiveObservationPhaseV0::DuringWave => {
48 ReactiveDivergenceDispositionV0::BenignUntilFlush
49 }
50 ReactiveObservationPhaseV0::Flush => ReactiveDivergenceDispositionV0::Blocker,
51 }
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58
59 const TAXONOMY: &str = include_str!("../docs/divergence-taxonomy.md");
60
61 #[test]
62 fn committed_taxonomy_and_machine_ids_are_in_lockstep() {
63 for class in ReactiveDivergenceClassV0::all() {
64 assert!(
65 TAXONOMY.contains(&format!("`{}`", class.id())),
66 "taxonomy must document {}",
67 class.id()
68 );
69 }
70 assert_eq!(TAXONOMY.matches("## Class:").count(), 2);
71 }
72
73 #[test]
74 fn reviewed_timing_classes_never_suppress_a_flush_mismatch() {
75 for class in ReactiveDivergenceClassV0::all() {
76 assert_eq!(
77 class.disposition(ReactiveObservationPhaseV0::DuringWave),
78 ReactiveDivergenceDispositionV0::BenignUntilFlush
79 );
80 assert_eq!(
81 class.disposition(ReactiveObservationPhaseV0::Flush),
82 ReactiveDivergenceDispositionV0::Blocker
83 );
84 }
85 assert!(ReactiveDivergenceClassV0::from_id("unreviewedDifference").is_none());
86 }
87}