ironflow_store/entities/
event_kind.rs1use serde::{Deserialize, Serialize};
4use strum::{Display, EnumString, IntoStaticStr};
5
6#[derive(
20 Debug,
21 Clone,
22 Copy,
23 PartialEq,
24 Eq,
25 Hash,
26 Serialize,
27 Deserialize,
28 Display,
29 EnumString,
30 IntoStaticStr,
31)]
32#[serde(rename_all = "snake_case")]
33#[strum(serialize_all = "snake_case")]
34#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
35pub enum EventKind {
36 RunCreated,
38 RunStatusChanged,
40 RunFailed,
42 RunBudgetExceeded,
44 StepCompleted,
46 StepFailed,
48 ApprovalRequested,
50 ApprovalGranted,
52 ApprovalRejected,
54 LogLine,
56 UserSignedIn,
58 UserSignedUp,
60 UserSignedOut,
62 SecretsRotated,
64 RetryForced,
66}
67
68impl EventKind {
69 pub const ALL: &'static [EventKind] = &[
71 Self::RunCreated,
72 Self::RunStatusChanged,
73 Self::RunFailed,
74 Self::RunBudgetExceeded,
75 Self::StepCompleted,
76 Self::StepFailed,
77 Self::ApprovalRequested,
78 Self::ApprovalGranted,
79 Self::ApprovalRejected,
80 Self::LogLine,
81 Self::UserSignedIn,
82 Self::UserSignedUp,
83 Self::UserSignedOut,
84 Self::SecretsRotated,
85 Self::RetryForced,
86 ];
87
88 pub fn as_str(self) -> &'static str {
99 self.into()
100 }
101}
102
103#[cfg(test)]
104mod tests {
105 use super::*;
106
107 #[test]
108 fn all_variants_roundtrip_via_str() {
109 for kind in EventKind::ALL {
110 let s = kind.as_str();
111 let parsed: EventKind = s.parse().unwrap();
112 assert_eq!(*kind, parsed);
113 }
114 }
115
116 #[test]
117 fn all_has_correct_count() {
118 assert_eq!(EventKind::ALL.len(), 15);
119 }
120
121 #[test]
122 fn secrets_rotated_uses_snake_case_wire_format() {
123 assert_eq!(EventKind::SecretsRotated.as_str(), "secrets_rotated");
124 assert_eq!(
125 "secrets_rotated".parse::<EventKind>().unwrap(),
126 EventKind::SecretsRotated
127 );
128 }
129
130 #[test]
131 fn run_budget_exceeded_uses_snake_case_wire_format() {
132 assert_eq!(EventKind::RunBudgetExceeded.as_str(), "run_budget_exceeded");
133 assert_eq!(
134 "run_budget_exceeded".parse::<EventKind>().unwrap(),
135 EventKind::RunBudgetExceeded
136 );
137 }
138
139 #[test]
140 fn display_matches_as_str() {
141 for kind in EventKind::ALL {
142 assert_eq!(kind.to_string(), kind.as_str());
143 }
144 }
145
146 #[test]
147 fn parse_unknown_returns_error() {
148 assert!("bogus".parse::<EventKind>().is_err());
149 }
150
151 #[test]
152 fn serde_roundtrip() {
153 let kind = EventKind::RunStatusChanged;
154 let json = serde_json::to_string(&kind).unwrap();
155 assert_eq!(json, "\"run_status_changed\"");
156 let back: EventKind = serde_json::from_str(&json).unwrap();
157 assert_eq!(back, kind);
158 }
159
160 #[test]
161 fn serde_all_variants() {
162 for kind in EventKind::ALL {
163 let json = serde_json::to_string(kind).unwrap();
164 let back: EventKind = serde_json::from_str(&json).unwrap();
165 assert_eq!(*kind, back);
166 }
167 }
168}