Skip to main content

dapr_durabletask/api/
orchestration_status.rs

1use std::fmt;
2
3/// The runtime status of an orchestration instance.
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
5pub enum OrchestrationStatus {
6    Running,
7    Completed,
8    ContinuedAsNew,
9    Failed,
10    Canceled,
11    Terminated,
12    Pending,
13    Suspended,
14    Stalled,
15}
16
17impl OrchestrationStatus {
18    /// Returns `true` if the orchestration has reached a terminal state
19    /// (completed, failed, cancelled, or terminated).
20    pub fn is_terminal(&self) -> bool {
21        matches!(
22            self,
23            Self::Completed | Self::Failed | Self::Canceled | Self::Terminated
24        )
25    }
26
27    /// Returns `true` if the orchestration is actively running.
28    pub fn is_running(&self) -> bool {
29        matches!(self, Self::Running)
30    }
31}
32
33impl TryFrom<i32> for OrchestrationStatus {
34    type Error = i32;
35
36    fn try_from(value: i32) -> std::result::Result<Self, Self::Error> {
37        match value {
38            0 => Ok(Self::Running),
39            1 => Ok(Self::Completed),
40            2 => Ok(Self::ContinuedAsNew),
41            3 => Ok(Self::Failed),
42            4 => Ok(Self::Canceled),
43            5 => Ok(Self::Terminated),
44            6 => Ok(Self::Pending),
45            7 => Ok(Self::Suspended),
46            8 => Ok(Self::Stalled),
47            _ => Err(value),
48        }
49    }
50}
51
52impl From<OrchestrationStatus> for i32 {
53    fn from(status: OrchestrationStatus) -> Self {
54        match status {
55            OrchestrationStatus::Running => 0,
56            OrchestrationStatus::Completed => 1,
57            OrchestrationStatus::ContinuedAsNew => 2,
58            OrchestrationStatus::Failed => 3,
59            OrchestrationStatus::Canceled => 4,
60            OrchestrationStatus::Terminated => 5,
61            OrchestrationStatus::Pending => 6,
62            OrchestrationStatus::Suspended => 7,
63            OrchestrationStatus::Stalled => 8,
64        }
65    }
66}
67
68impl fmt::Display for OrchestrationStatus {
69    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70        let s = match self {
71            Self::Running => "Running",
72            Self::Completed => "Completed",
73            Self::ContinuedAsNew => "ContinuedAsNew",
74            Self::Failed => "Failed",
75            Self::Canceled => "Canceled",
76            Self::Terminated => "Terminated",
77            Self::Pending => "Pending",
78            Self::Suspended => "Suspended",
79            Self::Stalled => "Stalled",
80        };
81        f.write_str(s)
82    }
83}
84
85#[cfg(test)]
86mod tests {
87    use super::*;
88
89    #[test]
90    fn test_roundtrip_conversion() {
91        for value in 0..=8 {
92            let status = OrchestrationStatus::try_from(value).unwrap();
93            let back: i32 = status.into();
94            assert_eq!(value, back);
95        }
96    }
97
98    #[test]
99    fn test_unknown_value_returns_error() {
100        assert!(OrchestrationStatus::try_from(99).is_err());
101    }
102
103    #[test]
104    fn test_is_terminal() {
105        assert!(OrchestrationStatus::Completed.is_terminal());
106        assert!(OrchestrationStatus::Failed.is_terminal());
107        assert!(OrchestrationStatus::Canceled.is_terminal());
108        assert!(OrchestrationStatus::Terminated.is_terminal());
109        assert!(!OrchestrationStatus::Running.is_terminal());
110        assert!(!OrchestrationStatus::Pending.is_terminal());
111    }
112
113    #[test]
114    fn test_is_running() {
115        assert!(OrchestrationStatus::Running.is_running());
116        assert!(!OrchestrationStatus::Completed.is_running());
117    }
118
119    #[test]
120    fn test_display() {
121        assert_eq!(OrchestrationStatus::Running.to_string(), "Running");
122        assert_eq!(OrchestrationStatus::Completed.to_string(), "Completed");
123        assert_eq!(
124            OrchestrationStatus::ContinuedAsNew.to_string(),
125            "ContinuedAsNew"
126        );
127        assert_eq!(OrchestrationStatus::Failed.to_string(), "Failed");
128        assert_eq!(OrchestrationStatus::Canceled.to_string(), "Canceled");
129        assert_eq!(OrchestrationStatus::Terminated.to_string(), "Terminated");
130        assert_eq!(OrchestrationStatus::Pending.to_string(), "Pending");
131        assert_eq!(OrchestrationStatus::Suspended.to_string(), "Suspended");
132        assert_eq!(OrchestrationStatus::Stalled.to_string(), "Stalled");
133    }
134}