1use core::fmt;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
28#[non_exhaustive]
29pub enum StopReason {
30 Cancelled,
35
36 TimedOut,
41}
42
43impl StopReason {
44 #[inline]
51 pub fn is_transient(&self) -> bool {
52 matches!(self, Self::TimedOut)
53 }
54
55 #[inline]
57 pub fn is_cancelled(&self) -> bool {
58 matches!(self, Self::Cancelled)
59 }
60
61 #[inline]
63 pub fn is_timed_out(&self) -> bool {
64 matches!(self, Self::TimedOut)
65 }
66}
67
68impl fmt::Display for StopReason {
69 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70 match self {
71 Self::Cancelled => write!(f, "operation cancelled"),
72 Self::TimedOut => write!(f, "operation timed out"),
73 }
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80
81 #[test]
82 fn stop_reason_display() {
83 extern crate alloc;
84 use alloc::format;
85 assert_eq!(format!("{}", StopReason::Cancelled), "operation cancelled");
86 assert_eq!(format!("{}", StopReason::TimedOut), "operation timed out");
87 }
88
89 #[test]
90 fn stop_reason_equality() {
91 assert_eq!(StopReason::Cancelled, StopReason::Cancelled);
92 assert_eq!(StopReason::TimedOut, StopReason::TimedOut);
93 assert_ne!(StopReason::Cancelled, StopReason::TimedOut);
94 }
95
96 #[test]
97 fn stop_reason_is_transient() {
98 assert!(!StopReason::Cancelled.is_transient());
99 assert!(StopReason::TimedOut.is_transient());
100 }
101
102 #[test]
103 fn stop_reason_copy() {
104 let a = StopReason::Cancelled;
105 let b = a; assert_eq!(a, b);
107 }
108
109 #[test]
110 fn stop_reason_hash() {
111 use core::hash::{Hash, Hasher};
112
113 struct DummyHasher(u64);
114 impl Hasher for DummyHasher {
115 fn finish(&self) -> u64 {
116 self.0
117 }
118 fn write(&mut self, bytes: &[u8]) {
119 for &b in bytes {
120 self.0 = self.0.wrapping_add(b as u64);
121 }
122 }
123 }
124
125 let mut h1 = DummyHasher(0);
126 let mut h2 = DummyHasher(0);
127 StopReason::Cancelled.hash(&mut h1);
128 StopReason::Cancelled.hash(&mut h2);
129 assert_eq!(h1.finish(), h2.finish());
130 }
131}