stateset_core/errors/
transition.rs1use std::fmt;
9
10#[derive(Clone, Copy, PartialEq, Eq, Hash)]
36pub struct StateTransitionError<S> {
37 pub from: S,
39 pub to: S,
41}
42
43impl<S> StateTransitionError<S> {
44 #[inline]
46 pub const fn new(from: S, to: S) -> Self {
47 Self { from, to }
48 }
49}
50
51impl<S: fmt::Display> fmt::Display for StateTransitionError<S> {
52 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53 write!(f, "invalid state transition from {} to {}", self.from, self.to)
54 }
55}
56
57impl<S: fmt::Debug> fmt::Debug for StateTransitionError<S> {
58 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
59 f.debug_struct("StateTransitionError")
60 .field("from", &self.from)
61 .field("to", &self.to)
62 .finish()
63 }
64}
65
66impl<S: fmt::Debug + fmt::Display> std::error::Error for StateTransitionError<S> {}
67
68#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
82pub struct GotExpected<T> {
83 pub got: T,
85 pub expected: T,
87}
88
89impl<T> GotExpected<T> {
90 #[inline]
92 pub const fn new(got: T, expected: T) -> Self {
93 Self { got, expected }
94 }
95}
96
97impl<T: fmt::Display> fmt::Display for GotExpected<T> {
98 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
99 write!(f, "expected {}, got {}", self.expected, self.got)
100 }
101}
102
103impl<T: fmt::Debug + fmt::Display> std::error::Error for GotExpected<T> {}
104
105#[cfg(test)]
106mod tests {
107 use super::*;
108
109 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
110 enum Status {
111 Pending,
112 Active,
113 Closed,
114 }
115
116 impl fmt::Display for Status {
117 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118 match self {
119 Self::Pending => write!(f, "pending"),
120 Self::Active => write!(f, "active"),
121 Self::Closed => write!(f, "closed"),
122 }
123 }
124 }
125
126 #[test]
127 fn transition_error_display() {
128 let err = StateTransitionError::new(Status::Pending, Status::Closed);
129 assert_eq!(err.to_string(), "invalid state transition from pending to closed");
130 }
131
132 #[test]
133 fn transition_error_debug() {
134 let err = StateTransitionError::new(Status::Active, Status::Pending);
135 let debug = format!("{:?}", err);
136 assert!(debug.contains("StateTransitionError"));
137 assert!(debug.contains("Active"));
138 assert!(debug.contains("Pending"));
139 }
140
141 #[test]
142 fn transition_error_fields() {
143 let err = StateTransitionError::new(Status::Active, Status::Closed);
144 assert_eq!(err.from, Status::Active);
145 assert_eq!(err.to, Status::Closed);
146 }
147
148 #[test]
149 fn got_expected_display() {
150 let ge = GotExpected { got: 3, expected: 5 };
151 assert_eq!(ge.to_string(), "expected 5, got 3");
152 }
153
154 #[test]
155 fn got_expected_with_strings() {
156 let ge = GotExpected { got: "foo".to_string(), expected: "bar".to_string() };
157 assert_eq!(ge.to_string(), "expected bar, got foo");
158 }
159}