Skip to main content

artifactize_core/monitor/model/
status.rs

1//! Every status the monitor shows, typed until it is drawn: the statuses of Runs, requests
2//! and Artifact validation, in their urgency order.
3
4use crate::types::{ArtifactValidationStatus, RequestStatus, RunStatus};
5
6/// A shown status. The variants are declared most urgent first, so the derived order is
7/// the urgency order the header, Scope, Runs and headline counts use.
8#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
9pub enum Status {
10    Error,
11    Red,
12    Blocked,
13    Running,
14    WaitingHuman,
15    Queued,
16    BudgetExhausted,
17    WaitDependency,
18    Wait,
19    Stale,
20    Unreviewed,
21    Incomplete,
22    Deferred,
23    Provisional,
24    SignoffsPending,
25    Green,
26    Basis,
27}
28
29impl Status {
30    /// The status as saved and printed, such as `WAITING_HUMAN`.
31    pub fn as_str(self) -> &'static str {
32        match self {
33            Self::Error => "ERROR",
34            Self::Red => "RED",
35            Self::Blocked => "BLOCKED",
36            Self::Running => "RUNNING",
37            Self::WaitingHuman => "WAITING_HUMAN",
38            Self::Queued => "QUEUED",
39            Self::BudgetExhausted => "BUDGET_EXHAUSTED",
40            Self::WaitDependency => "WAIT_DEPENDENCY",
41            Self::Wait => "WAIT",
42            Self::Stale => "STALE",
43            Self::Unreviewed => "UNREVIEWED",
44            Self::Incomplete => "INCOMPLETE",
45            Self::Deferred => "DEFERRED",
46            Self::Provisional => "PROVISIONAL",
47            Self::SignoffsPending => "SIGNOFFS_PENDING",
48            Self::Green => "GREEN",
49            Self::Basis => "BASIS",
50        }
51    }
52
53    /// The one-character mark the tree, counts and headline show for the status.
54    pub fn glyph(self) -> &'static str {
55        match self {
56            Self::Green => "✓",
57            Self::Red => "✗",
58            Self::Error => "!",
59            Self::Running => "◐",
60            Self::WaitingHuman | Self::Deferred | Self::SignoffsPending => "?",
61            Self::Provisional => "○",
62            Self::Queued => "·",
63            Self::Blocked => "⊘",
64            Self::WaitDependency | Self::Wait => "…",
65            Self::BudgetExhausted => "$",
66            Self::Basis => "◇",
67            Self::Stale | Self::Unreviewed | Self::Incomplete => "○",
68        }
69    }
70
71    /// What a request in this status means, for its detail.
72    pub fn meaning(self) -> &'static str {
73        match self {
74            Self::Green => "criteria met",
75            Self::Red => "criteria not met",
76            Self::Error => "operational failure, not a verdict",
77            Self::Running => "executing",
78            Self::WaitingHuman => "waiting for a Human submission",
79            Self::Deferred => "sign-off deferred; execution may proceed",
80            Self::Provisional => "criteria met; dependent sign-offs remain",
81            Self::SignoffsPending => "only sign-offs remain",
82            Self::Blocked => "blocked by a RED dependency",
83            Self::WaitDependency => "waiting for current GREEN dependency evidence",
84            Self::BudgetExhausted => "maxExecutions reached before it started",
85            _ => "not executed",
86        }
87    }
88}
89
90impl std::fmt::Display for Status {
91    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
92        formatter.write_str(self.as_str())
93    }
94}
95
96impl From<RunStatus> for Status {
97    fn from(status: RunStatus) -> Self {
98        match status {
99            RunStatus::Running => Self::Running,
100            RunStatus::Green => Self::Green,
101            RunStatus::Red => Self::Red,
102            RunStatus::Error => Self::Error,
103            RunStatus::Incomplete => Self::Incomplete,
104            RunStatus::SignoffsPending => Self::SignoffsPending,
105        }
106    }
107}
108
109impl From<RequestStatus> for Status {
110    fn from(status: RequestStatus) -> Self {
111        match status {
112            RequestStatus::Queued => Self::Queued,
113            RequestStatus::Running => Self::Running,
114            RequestStatus::WaitingHuman => Self::WaitingHuman,
115            RequestStatus::Deferred => Self::Deferred,
116            RequestStatus::Provisional => Self::Provisional,
117            RequestStatus::Green => Self::Green,
118            RequestStatus::Red => Self::Red,
119            RequestStatus::Error => Self::Error,
120            RequestStatus::BudgetExhausted => Self::BudgetExhausted,
121            RequestStatus::Stale => Self::Stale,
122            RequestStatus::Unreviewed => Self::Unreviewed,
123            RequestStatus::WaitDependency => Self::WaitDependency,
124            RequestStatus::Blocked => Self::Blocked,
125        }
126    }
127}
128
129impl From<ArtifactValidationStatus> for Status {
130    fn from(status: ArtifactValidationStatus) -> Self {
131        match status {
132            ArtifactValidationStatus::Basis => Self::Basis,
133            ArtifactValidationStatus::Deferred => Self::Deferred,
134            ArtifactValidationStatus::Provisional => Self::Provisional,
135            ArtifactValidationStatus::Green => Self::Green,
136            ArtifactValidationStatus::Incomplete => Self::Incomplete,
137            ArtifactValidationStatus::Error => Self::Error,
138            ArtifactValidationStatus::Red => Self::Red,
139            ArtifactValidationStatus::Blocked => Self::Blocked,
140            ArtifactValidationStatus::Wait => Self::Wait,
141            ArtifactValidationStatus::Stale => Self::Stale,
142            ArtifactValidationStatus::Unreviewed => Self::Unreviewed,
143        }
144    }
145}