Skip to main content

made_core/value_objects/ceremony/
step_status.rs

1use serde::{Deserialize, Serialize};
2
3use crate::error::DomainError;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
6#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
7pub enum StepStatus {
8    Pending,
9    InProgress,
10    Completed,
11    Failed,
12    WaitingForHuman,
13    Cancelled,
14}
15
16impl StepStatus {
17    #[must_use]
18    pub fn is_executable(self) -> bool {
19        matches!(self, Self::Pending | Self::Failed | Self::WaitingForHuman)
20    }
21
22    #[must_use]
23    pub fn is_terminal(self) -> bool {
24        matches!(self, Self::Completed | Self::Failed | Self::Cancelled)
25    }
26
27    #[must_use]
28    pub fn is_success(self) -> bool {
29        self == Self::Completed
30    }
31
32    /// Stable, low-cardinality label value for metrics exposition.
33    #[must_use]
34    pub const fn as_label(self) -> &'static str {
35        match self {
36            Self::Pending => "pending",
37            Self::InProgress => "in_progress",
38            Self::Completed => "completed",
39            Self::Failed => "failed",
40            Self::WaitingForHuman => "waiting_for_human",
41            Self::Cancelled => "cancelled",
42        }
43    }
44}
45
46impl TryFrom<&str> for StepStatus {
47    type Error = DomainError;
48
49    fn try_from(value: &str) -> Result<Self, Self::Error> {
50        match value {
51            "PENDING" => Ok(Self::Pending),
52            "IN_PROGRESS" => Ok(Self::InProgress),
53            "COMPLETED" => Ok(Self::Completed),
54            "FAILED" => Ok(Self::Failed),
55            "WAITING_FOR_HUMAN" => Ok(Self::WaitingForHuman),
56            "CANCELLED" => Ok(Self::Cancelled),
57            _ => Err(DomainError::InvariantViolated {
58                reason: "unknown ceremony step status",
59            }),
60        }
61    }
62}