Skip to main content

canic_core/domain/
runtime.rs

1//! Module: domain::runtime
2//!
3//! Responsibility: define pure runtime value enums shared by runtime ops,
4//! status builders, and endpoint DTOs.
5//! Does not own: runtime status DTO structs, endpoint guards, or runtime
6//! mutation.
7//! Boundary: DTOs re-export these values to preserve the public API path while
8//! internal code imports them from the domain owner.
9
10use candid::CandidType;
11use serde::{Deserialize, Serialize};
12
13// CandidType supports explicit serde(rename) labels, but not rename_all. Keep
14// runtime introspection enum labels canonical and alias-free.
15
16///
17/// FailureSeverity
18///
19
20#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
21pub enum FailureSeverity {
22    #[serde(rename = "info")]
23    Info,
24    #[serde(rename = "warning")]
25    Warning,
26    #[serde(rename = "error")]
27    Error,
28    #[serde(rename = "critical")]
29    Critical,
30}
31
32impl FailureSeverity {
33    #[must_use]
34    pub const fn label(self) -> &'static str {
35        match self {
36            Self::Info => "info",
37            Self::Warning => "warning",
38            Self::Error => "error",
39            Self::Critical => "critical",
40        }
41    }
42}
43
44///
45/// RuntimeFieldVisibility
46///
47
48#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
49pub enum RuntimeFieldVisibility {
50    #[serde(rename = "public_safe")]
51    PublicSafe,
52    #[serde(rename = "operator_only")]
53    OperatorOnly,
54    #[serde(rename = "controller_only")]
55    ControllerOnly,
56    #[serde(rename = "feature_gated")]
57    FeatureGated,
58    #[serde(rename = "disabled")]
59    Disabled,
60}
61
62impl RuntimeFieldVisibility {
63    #[must_use]
64    pub const fn label(self) -> &'static str {
65        match self {
66            Self::PublicSafe => "public_safe",
67            Self::OperatorOnly => "operator_only",
68            Self::ControllerOnly => "controller_only",
69            Self::FeatureGated => "feature_gated",
70            Self::Disabled => "disabled",
71        }
72    }
73}
74
75///
76/// RuntimeCheckStatus
77///
78
79#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
80pub enum RuntimeCheckStatus {
81    #[serde(rename = "pass")]
82    Pass,
83    #[serde(rename = "warn")]
84    Warn,
85    #[serde(rename = "fail")]
86    Fail,
87    #[serde(rename = "not_evaluated")]
88    NotEvaluated,
89}
90
91impl RuntimeCheckStatus {
92    #[must_use]
93    pub const fn label(self) -> &'static str {
94        match self {
95            Self::Pass => "pass",
96            Self::Warn => "warn",
97            Self::Fail => "fail",
98            Self::NotEvaluated => "not_evaluated",
99        }
100    }
101}
102
103///
104/// RuntimeDiagnosticSeverity
105///
106
107#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
108pub enum RuntimeDiagnosticSeverity {
109    #[serde(rename = "info")]
110    Info,
111    #[serde(rename = "warning")]
112    Warning,
113    #[serde(rename = "blocked")]
114    Blocked,
115    #[serde(rename = "unsupported")]
116    Unsupported,
117}
118
119impl RuntimeDiagnosticSeverity {
120    #[must_use]
121    pub const fn label(self) -> &'static str {
122        match self {
123            Self::Info => "info",
124            Self::Warning => "warning",
125            Self::Blocked => "blocked",
126            Self::Unsupported => "unsupported",
127        }
128    }
129}
130
131///
132/// RuntimeStateDomainStatus
133///
134
135#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
136pub enum RuntimeStateDomainStatus {
137    #[serde(rename = "ok")]
138    Ok,
139    #[serde(rename = "warning")]
140    Warning,
141    #[serde(rename = "failing")]
142    Failing,
143    #[serde(rename = "not_evaluated")]
144    NotEvaluated,
145}
146
147impl RuntimeStateDomainStatus {
148    #[must_use]
149    pub const fn label(self) -> &'static str {
150        match self {
151            Self::Ok => "ok",
152            Self::Warning => "warning",
153            Self::Failing => "failing",
154            Self::NotEvaluated => "not_evaluated",
155        }
156    }
157}
158
159///
160/// HealthStatus
161///
162
163#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
164pub enum HealthStatus {
165    #[serde(rename = "healthy")]
166    Healthy,
167    #[serde(rename = "degraded")]
168    Degraded,
169    #[serde(rename = "unhealthy")]
170    Unhealthy,
171    #[serde(rename = "unknown")]
172    Unknown,
173}
174
175impl HealthStatus {
176    #[must_use]
177    pub const fn label(self) -> &'static str {
178        match self {
179            Self::Healthy => "healthy",
180            Self::Degraded => "degraded",
181            Self::Unhealthy => "unhealthy",
182            Self::Unknown => "unknown",
183        }
184    }
185}
186
187///
188/// ReadinessStatus
189///
190
191#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
192pub enum ReadinessStatus {
193    #[serde(rename = "ready")]
194    Ready,
195    #[serde(rename = "degraded")]
196    Degraded,
197    #[serde(rename = "not_ready")]
198    NotReady,
199    #[serde(rename = "not_evaluated")]
200    NotEvaluated,
201}
202
203impl ReadinessStatus {
204    #[must_use]
205    pub const fn label(self) -> &'static str {
206        match self {
207            Self::Ready => "ready",
208            Self::Degraded => "degraded",
209            Self::NotReady => "not_ready",
210            Self::NotEvaluated => "not_evaluated",
211        }
212    }
213}
214
215///
216/// RuntimeStatus
217///
218
219#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
220pub enum RuntimeStatus {
221    #[serde(rename = "ok")]
222    Ok,
223    #[serde(rename = "degraded")]
224    Degraded,
225    #[serde(rename = "failing")]
226    Failing,
227    #[serde(rename = "unknown")]
228    Unknown,
229}
230
231impl RuntimeStatus {
232    #[must_use]
233    pub const fn label(self) -> &'static str {
234        match self {
235            Self::Ok => "ok",
236            Self::Degraded => "degraded",
237            Self::Failing => "failing",
238            Self::Unknown => "unknown",
239        }
240    }
241}
242
243///
244/// TimerStatus
245///
246
247#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
248pub enum TimerStatus {
249    #[serde(rename = "healthy")]
250    Healthy,
251    #[serde(rename = "delayed")]
252    Delayed,
253    #[serde(rename = "failing")]
254    Failing,
255    #[serde(rename = "disabled")]
256    Disabled,
257    #[serde(rename = "not_registered")]
258    NotRegistered,
259    #[serde(rename = "unknown")]
260    Unknown,
261}
262
263impl TimerStatus {
264    #[must_use]
265    pub const fn label(self) -> &'static str {
266        match self {
267            Self::Healthy => "healthy",
268            Self::Delayed => "delayed",
269            Self::Failing => "failing",
270            Self::Disabled => "disabled",
271            Self::NotRegistered => "not_registered",
272            Self::Unknown => "unknown",
273        }
274    }
275}
276
277///
278/// TimerMode
279///
280
281#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
282#[remain::sorted]
283pub enum TimerMode {
284    Interval,
285    Once,
286}
287
288#[cfg(test)]
289mod tests {
290    use super::*;
291
292    #[test]
293    fn runtime_enums_own_serialized_labels() {
294        assert_eq!(FailureSeverity::Info.label(), "info");
295        assert_eq!(FailureSeverity::Warning.label(), "warning");
296        assert_eq!(FailureSeverity::Error.label(), "error");
297        assert_eq!(FailureSeverity::Critical.label(), "critical");
298
299        assert_eq!(RuntimeFieldVisibility::PublicSafe.label(), "public_safe");
300        assert_eq!(
301            RuntimeFieldVisibility::OperatorOnly.label(),
302            "operator_only"
303        );
304        assert_eq!(
305            RuntimeFieldVisibility::ControllerOnly.label(),
306            "controller_only"
307        );
308        assert_eq!(
309            RuntimeFieldVisibility::FeatureGated.label(),
310            "feature_gated"
311        );
312        assert_eq!(RuntimeFieldVisibility::Disabled.label(), "disabled");
313
314        assert_eq!(RuntimeCheckStatus::Pass.label(), "pass");
315        assert_eq!(RuntimeCheckStatus::Warn.label(), "warn");
316        assert_eq!(RuntimeCheckStatus::Fail.label(), "fail");
317        assert_eq!(RuntimeCheckStatus::NotEvaluated.label(), "not_evaluated");
318
319        assert_eq!(RuntimeDiagnosticSeverity::Info.label(), "info");
320        assert_eq!(RuntimeDiagnosticSeverity::Warning.label(), "warning");
321        assert_eq!(RuntimeDiagnosticSeverity::Blocked.label(), "blocked");
322        assert_eq!(
323            RuntimeDiagnosticSeverity::Unsupported.label(),
324            "unsupported"
325        );
326
327        assert_eq!(RuntimeStateDomainStatus::Ok.label(), "ok");
328        assert_eq!(RuntimeStateDomainStatus::Warning.label(), "warning");
329        assert_eq!(RuntimeStateDomainStatus::Failing.label(), "failing");
330        assert_eq!(
331            RuntimeStateDomainStatus::NotEvaluated.label(),
332            "not_evaluated"
333        );
334
335        assert_eq!(HealthStatus::Healthy.label(), "healthy");
336        assert_eq!(HealthStatus::Degraded.label(), "degraded");
337        assert_eq!(HealthStatus::Unhealthy.label(), "unhealthy");
338        assert_eq!(HealthStatus::Unknown.label(), "unknown");
339
340        assert_eq!(ReadinessStatus::Ready.label(), "ready");
341        assert_eq!(ReadinessStatus::Degraded.label(), "degraded");
342        assert_eq!(ReadinessStatus::NotReady.label(), "not_ready");
343        assert_eq!(ReadinessStatus::NotEvaluated.label(), "not_evaluated");
344
345        assert_eq!(RuntimeStatus::Ok.label(), "ok");
346        assert_eq!(RuntimeStatus::Degraded.label(), "degraded");
347        assert_eq!(RuntimeStatus::Failing.label(), "failing");
348        assert_eq!(RuntimeStatus::Unknown.label(), "unknown");
349
350        assert_eq!(TimerStatus::Healthy.label(), "healthy");
351        assert_eq!(TimerStatus::Delayed.label(), "delayed");
352        assert_eq!(TimerStatus::Failing.label(), "failing");
353        assert_eq!(TimerStatus::Disabled.label(), "disabled");
354        assert_eq!(TimerStatus::NotRegistered.label(), "not_registered");
355        assert_eq!(TimerStatus::Unknown.label(), "unknown");
356    }
357}