1use core::fmt;
6
7#[cfg(feature = "std")]
8use std::error::Error as StdError;
9
10pub type Result<T> = core::result::Result<T, EmbeddedError>;
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
17#[non_exhaustive]
18pub enum EmbeddedError {
19 AllocationFailed,
21
22 PoolExhausted,
24
25 BufferTooSmall {
27 required: usize,
29 available: usize,
31 },
32
33 InvalidAlignment {
35 required: usize,
37 actual: usize,
39 },
40
41 UnsupportedOperation,
43
44 InvalidParameter,
46
47 OutOfBounds {
49 index: usize,
51 max: usize,
53 },
54
55 PowerModeTransitionFailed,
57
58 DeadlineMissed {
60 actual_us: u64,
62 deadline_us: u64,
64 },
65
66 ResourceBusy,
68
69 Timeout,
71
72 InitializationFailed,
74
75 HardwareError,
77
78 InvalidState,
80
81 FormatError,
83
84 ChecksumMismatch,
86
87 TargetSpecific(u8),
89}
90
91impl EmbeddedError {
92 pub const fn is_recoverable(&self) -> bool {
94 matches!(
95 self,
96 Self::BufferTooSmall { .. }
97 | Self::ResourceBusy
98 | Self::Timeout
99 | Self::DeadlineMissed { .. }
100 )
101 }
102
103 pub const fn is_resource_exhaustion(&self) -> bool {
105 matches!(
106 self,
107 Self::AllocationFailed | Self::PoolExhausted | Self::BufferTooSmall { .. }
108 )
109 }
110
111 pub const fn is_validation_error(&self) -> bool {
113 matches!(
114 self,
115 Self::InvalidParameter
116 | Self::InvalidAlignment { .. }
117 | Self::OutOfBounds { .. }
118 | Self::FormatError
119 | Self::ChecksumMismatch
120 )
121 }
122
123 pub const fn error_code(&self) -> u32 {
125 match self {
126 Self::AllocationFailed => 1,
127 Self::PoolExhausted => 2,
128 Self::BufferTooSmall { .. } => 3,
129 Self::InvalidAlignment { .. } => 4,
130 Self::UnsupportedOperation => 5,
131 Self::InvalidParameter => 6,
132 Self::OutOfBounds { .. } => 7,
133 Self::PowerModeTransitionFailed => 8,
134 Self::DeadlineMissed { .. } => 9,
135 Self::ResourceBusy => 10,
136 Self::Timeout => 11,
137 Self::InitializationFailed => 12,
138 Self::HardwareError => 13,
139 Self::InvalidState => 14,
140 Self::FormatError => 15,
141 Self::ChecksumMismatch => 16,
142 Self::TargetSpecific(_) => 100,
143 }
144 }
145}
146
147impl fmt::Display for EmbeddedError {
148 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
149 match self {
150 Self::AllocationFailed => write!(f, "Memory allocation failed"),
151 Self::PoolExhausted => write!(f, "Memory pool exhausted"),
152 Self::BufferTooSmall {
153 required,
154 available,
155 } => write!(
156 f,
157 "Buffer too small: required {} bytes, available {} bytes",
158 required, available
159 ),
160 Self::InvalidAlignment { required, actual } => write!(
161 f,
162 "Invalid alignment: required {}, got {}",
163 required, actual
164 ),
165 Self::UnsupportedOperation => write!(f, "Operation not supported"),
166 Self::InvalidParameter => write!(f, "Invalid parameter"),
167 Self::OutOfBounds { index, max } => {
168 write!(f, "Out of bounds: index {} exceeds max {}", index, max)
169 }
170 Self::PowerModeTransitionFailed => write!(f, "Power mode transition failed"),
171 Self::DeadlineMissed {
172 actual_us,
173 deadline_us,
174 } => write!(
175 f,
176 "Real-time deadline missed: {} us > {} us",
177 actual_us, deadline_us
178 ),
179 Self::ResourceBusy => write!(f, "Resource is busy"),
180 Self::Timeout => write!(f, "Operation timed out"),
181 Self::InitializationFailed => write!(f, "Initialization failed"),
182 Self::HardwareError => write!(f, "Hardware error"),
183 Self::InvalidState => write!(f, "Invalid state"),
184 Self::FormatError => write!(f, "Data format error"),
185 Self::ChecksumMismatch => write!(f, "Checksum mismatch"),
186 Self::TargetSpecific(code) => write!(f, "Target-specific error: {}", code),
187 }
188 }
189}
190
191#[cfg(feature = "std")]
192impl StdError for EmbeddedError {}
193
194#[cfg(test)]
195mod tests {
196 use super::*;
197
198 #[test]
199 fn test_error_categories() {
200 let err = EmbeddedError::BufferTooSmall {
201 required: 100,
202 available: 50,
203 };
204 assert!(err.is_recoverable());
205 assert!(err.is_resource_exhaustion());
206 assert!(!err.is_validation_error());
207
208 let err = EmbeddedError::InvalidParameter;
209 assert!(!err.is_recoverable());
210 assert!(!err.is_resource_exhaustion());
211 assert!(err.is_validation_error());
212 }
213
214 #[test]
215 fn test_error_codes() {
216 assert_eq!(EmbeddedError::AllocationFailed.error_code(), 1);
217 assert_eq!(EmbeddedError::PoolExhausted.error_code(), 2);
218 assert_eq!(EmbeddedError::TargetSpecific(42).error_code(), 100);
219 }
220}