Skip to main content

ironflow_store/entities/
step_status.rs

1//! [`StepStatus`] — lifecycle states for a workflow step.
2
3use serde::{Deserialize, Serialize};
4
5/// Status of an individual step within a run.
6///
7/// # Examples
8///
9/// ```
10/// use ironflow_store::entities::StepStatus;
11///
12/// assert!(!StepStatus::Pending.is_terminal());
13/// assert!(StepStatus::Completed.is_terminal());
14/// ```
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
16#[serde(rename_all = "snake_case")]
17pub enum StepStatus {
18    /// Waiting to execute.
19    Pending,
20    /// Currently executing.
21    Running,
22    /// Executed successfully.
23    Completed,
24    /// Execution failed.
25    Failed,
26    /// Skipped (e.g. when a prior step failed).
27    Skipped,
28    /// Waiting for human approval before continuing.
29    AwaitingApproval,
30    /// Human rejected the approval request.
31    Rejected,
32}
33
34impl StepStatus {
35    /// Returns `true` if this is a terminal state.
36    pub fn is_terminal(&self) -> bool {
37        matches!(
38            self,
39            StepStatus::Completed | StepStatus::Failed | StepStatus::Skipped | StepStatus::Rejected
40        )
41    }
42}
43
44impl std::fmt::Display for StepStatus {
45    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46        match self {
47            StepStatus::Pending => f.write_str("Pending"),
48            StepStatus::Running => f.write_str("Running"),
49            StepStatus::Completed => f.write_str("Completed"),
50            StepStatus::Failed => f.write_str("Failed"),
51            StepStatus::Skipped => f.write_str("Skipped"),
52            StepStatus::AwaitingApproval => f.write_str("AwaitingApproval"),
53            StepStatus::Rejected => f.write_str("Rejected"),
54        }
55    }
56}
57
58#[cfg(test)]
59mod tests {
60    use super::*;
61
62    #[test]
63    fn terminal() {
64        assert!(StepStatus::Completed.is_terminal());
65        assert!(StepStatus::Failed.is_terminal());
66        assert!(StepStatus::Skipped.is_terminal());
67        assert!(!StepStatus::Pending.is_terminal());
68        assert!(!StepStatus::Running.is_terminal());
69        assert!(!StepStatus::AwaitingApproval.is_terminal());
70        assert!(StepStatus::Rejected.is_terminal());
71    }
72
73    #[test]
74    fn display() {
75        assert_eq!(StepStatus::Pending.to_string(), "Pending");
76        assert_eq!(StepStatus::Running.to_string(), "Running");
77        assert_eq!(StepStatus::Completed.to_string(), "Completed");
78        assert_eq!(StepStatus::Failed.to_string(), "Failed");
79        assert_eq!(StepStatus::Skipped.to_string(), "Skipped");
80        assert_eq!(StepStatus::AwaitingApproval.to_string(), "AwaitingApproval");
81        assert_eq!(StepStatus::Rejected.to_string(), "Rejected");
82    }
83}