mindset/builder/
macros.rs1#[macro_export]
22macro_rules! state_enum {
23 (
24 $(#[$meta:meta])*
25 $vis:vis enum $name:ident {
26 $(
27 $(#[$variant_meta:meta])*
28 $variant:ident
29 ),* $(,)?
30 }
31
32 $(final: [$($final:ident),* $(,)?])?
33 $(error: [$($error:ident),* $(,)?])?
34 ) => {
35 $(#[$meta])*
36 #[derive(Clone, PartialEq, Debug, serde::Serialize, serde::Deserialize)]
37 $vis enum $name {
38 $(
39 $(#[$variant_meta])*
40 $variant
41 ),*
42 }
43
44 impl $crate::core::State for $name {
45 fn name(&self) -> &str {
46 match self {
47 $(Self::$variant => stringify!($variant)),*
48 }
49 }
50
51 fn is_final(&self) -> bool {
52 match self {
53 $($(Self::$final => true,)*)?
54 _ => false,
55 }
56 }
57
58 fn is_error(&self) -> bool {
59 match self {
60 $($(Self::$error => true,)*)?
61 _ => false,
62 }
63 }
64 }
65 };
66}
67
68#[cfg(test)]
69mod tests {
70 use crate::core::State;
71
72 state_enum! {
73 enum TestState {
74 Initial,
75 Processing,
76 Complete,
77 Failed,
78 }
79 final: [Complete, Failed]
80 error: [Failed]
81 }
82
83 #[test]
84 fn state_enum_macro_generates_trait() {
85 let state = TestState::Initial;
86 assert_eq!(state.name(), "Initial");
87 assert!(!state.is_final());
88 assert!(!state.is_error());
89
90 let complete = TestState::Complete;
91 assert!(complete.is_final());
92 assert!(!complete.is_error());
93
94 let failed = TestState::Failed;
95 assert!(failed.is_final());
96 assert!(failed.is_error());
97 }
98
99 #[test]
100 fn state_enum_supports_visibility() {
101 state_enum! {
103 pub enum PublicState {
104 A,
105 B,
106 }
107 final: [B]
108 }
109
110 let _state = PublicState::A;
111 }
112
113 #[test]
114 fn state_enum_works_without_final_error() {
115 state_enum! {
116 enum MinimalState {
117 One,
118 Two,
119 }
120 }
121
122 let state = MinimalState::One;
123 assert!(!state.is_final());
124 assert!(!state.is_error());
125 }
126}