adze_bdd_scenario_core/
lib.rs1#![forbid(unsafe_op_in_unsafe_fn)]
7#![deny(missing_docs)]
8#![cfg_attr(feature = "strict_api", deny(unreachable_pub))]
9#![cfg_attr(not(feature = "strict_api"), warn(unreachable_pub))]
10#![cfg_attr(feature = "strict_docs", deny(missing_docs))]
11#![cfg_attr(not(feature = "strict_docs"), allow(missing_docs))]
12
13use core::fmt;
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
26pub enum BddPhase {
27 Core,
29 Runtime,
31}
32
33impl fmt::Display for BddPhase {
34 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35 write!(f, "{self:?}")
36 }
37}
38
39#[derive(Debug, Clone, Copy, PartialEq, Eq)]
55pub enum BddScenarioStatus {
56 Implemented,
58 Deferred {
60 reason: &'static str,
62 },
63}
64
65impl fmt::Display for BddScenarioStatus {
66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67 match self {
68 Self::Implemented => write!(f, "Implemented"),
69 Self::Deferred { reason } => write!(f, "Deferred: {reason}"),
70 }
71 }
72}
73
74impl BddScenarioStatus {
75 pub const fn implemented(self) -> bool {
77 matches!(self, Self::Implemented)
78 }
79
80 pub const fn icon(self) -> &'static str {
82 match self {
83 Self::Implemented => "✅",
84 Self::Deferred { .. } => "⏳",
85 }
86 }
87
88 pub const fn label(self) -> &'static str {
90 match self {
91 Self::Implemented => "IMPLEMENTED",
92 Self::Deferred { .. } => "DEFERRED",
93 }
94 }
95
96 pub const fn detail(self) -> &'static str {
98 match self {
99 Self::Implemented => "",
100 Self::Deferred { reason } => reason,
101 }
102 }
103}
104
105#[derive(Debug, Clone, Copy, PartialEq, Eq)]
107pub struct BddScenario {
108 pub id: u8,
110 pub title: &'static str,
112 pub reference: &'static str,
114 pub core_status: BddScenarioStatus,
116 pub runtime_status: BddScenarioStatus,
118}
119
120impl BddScenario {
121 pub const fn status(self, phase: BddPhase) -> BddScenarioStatus {
123 match phase {
124 BddPhase::Core => self.core_status,
125 BddPhase::Runtime => self.runtime_status,
126 }
127 }
128}
129
130impl fmt::Display for BddScenario {
131 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
132 write!(f, "Scenario {}: {}", self.id, self.title)
133 }
134}
135
136#[cfg(test)]
137mod tests {
138 use super::*;
139
140 #[test]
141 fn status_helpers_work() {
142 let done = BddScenarioStatus::Implemented;
143 assert!(done.implemented());
144 assert_eq!(done.icon(), "✅");
145 assert_eq!(done.label(), "IMPLEMENTED");
146 assert_eq!(done.detail(), "");
147
148 let deferred = BddScenarioStatus::Deferred { reason: "wip" };
149 assert!(!deferred.implemented());
150 assert_eq!(deferred.icon(), "⏳");
151 assert_eq!(deferred.label(), "DEFERRED");
152 assert_eq!(deferred.detail(), "wip");
153 }
154
155 #[test]
156 fn scenario_returns_status_for_phase() {
157 let scenario = BddScenario {
158 id: 7,
159 title: "GLR runtime explores both paths",
160 reference: "docs/archive/plans/BDD_GLR_CONFLICT_PRESERVATION.md",
161 core_status: BddScenarioStatus::Deferred { reason: "pending" },
162 runtime_status: BddScenarioStatus::Implemented,
163 };
164
165 assert_eq!(scenario.status(BddPhase::Core), scenario.core_status);
166 assert_eq!(scenario.status(BddPhase::Runtime), scenario.runtime_status);
167 }
168}