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 NoPowerController,
66
67 DeadlineMissed {
69 actual_us: u64,
71 deadline_us: u64,
73 },
74
75 ResourceBusy,
77
78 Timeout,
80
81 InitializationFailed,
83
84 HardwareError,
86
87 InvalidState,
89
90 FormatError,
92
93 ChecksumMismatch,
95
96 TargetSpecific(u8),
98}
99
100impl EmbeddedError {
101 pub const fn is_recoverable(&self) -> bool {
103 matches!(
104 self,
105 Self::BufferTooSmall { .. }
106 | Self::ResourceBusy
107 | Self::Timeout
108 | Self::DeadlineMissed { .. }
109 )
110 }
111
112 pub const fn is_resource_exhaustion(&self) -> bool {
114 matches!(
115 self,
116 Self::AllocationFailed | Self::PoolExhausted | Self::BufferTooSmall { .. }
117 )
118 }
119
120 pub const fn is_validation_error(&self) -> bool {
122 matches!(
123 self,
124 Self::InvalidParameter
125 | Self::InvalidAlignment { .. }
126 | Self::OutOfBounds { .. }
127 | Self::FormatError
128 | Self::ChecksumMismatch
129 )
130 }
131
132 pub const fn error_code(&self) -> u32 {
134 match self {
135 Self::AllocationFailed => 1,
136 Self::PoolExhausted => 2,
137 Self::BufferTooSmall { .. } => 3,
138 Self::InvalidAlignment { .. } => 4,
139 Self::UnsupportedOperation => 5,
140 Self::InvalidParameter => 6,
141 Self::OutOfBounds { .. } => 7,
142 Self::PowerModeTransitionFailed => 8,
143 Self::NoPowerController => 17,
144 Self::DeadlineMissed { .. } => 9,
145 Self::ResourceBusy => 10,
146 Self::Timeout => 11,
147 Self::InitializationFailed => 12,
148 Self::HardwareError => 13,
149 Self::InvalidState => 14,
150 Self::FormatError => 15,
151 Self::ChecksumMismatch => 16,
152 Self::TargetSpecific(_) => 100,
153 }
154 }
155}
156
157impl fmt::Display for EmbeddedError {
158 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
159 match self {
160 Self::AllocationFailed => write!(f, "Memory allocation failed"),
161 Self::PoolExhausted => write!(f, "Memory pool exhausted"),
162 Self::BufferTooSmall {
163 required,
164 available,
165 } => write!(
166 f,
167 "Buffer too small: required {} bytes, available {} bytes",
168 required, available
169 ),
170 Self::InvalidAlignment { required, actual } => write!(
171 f,
172 "Invalid alignment: required {}, got {}",
173 required, actual
174 ),
175 Self::UnsupportedOperation => write!(f, "Operation not supported"),
176 Self::InvalidParameter => write!(f, "Invalid parameter"),
177 Self::OutOfBounds { index, max } => {
178 write!(f, "Out of bounds: index {} exceeds max {}", index, max)
179 }
180 Self::PowerModeTransitionFailed => write!(f, "Power mode transition failed"),
181 Self::NoPowerController => {
182 write!(f, "No hardware power controller installed")
183 }
184 Self::DeadlineMissed {
185 actual_us,
186 deadline_us,
187 } => write!(
188 f,
189 "Real-time deadline missed: {} us > {} us",
190 actual_us, deadline_us
191 ),
192 Self::ResourceBusy => write!(f, "Resource is busy"),
193 Self::Timeout => write!(f, "Operation timed out"),
194 Self::InitializationFailed => write!(f, "Initialization failed"),
195 Self::HardwareError => write!(f, "Hardware error"),
196 Self::InvalidState => write!(f, "Invalid state"),
197 Self::FormatError => write!(f, "Data format error"),
198 Self::ChecksumMismatch => write!(f, "Checksum mismatch"),
199 Self::TargetSpecific(code) => write!(f, "Target-specific error: {}", code),
200 }
201 }
202}
203
204#[cfg(feature = "std")]
205impl StdError for EmbeddedError {}
206
207#[cfg(test)]
208mod tests {
209 use super::*;
210
211 #[test]
212 fn test_error_categories() {
213 let err = EmbeddedError::BufferTooSmall {
214 required: 100,
215 available: 50,
216 };
217 assert!(err.is_recoverable());
218 assert!(err.is_resource_exhaustion());
219 assert!(!err.is_validation_error());
220
221 let err = EmbeddedError::InvalidParameter;
222 assert!(!err.is_recoverable());
223 assert!(!err.is_resource_exhaustion());
224 assert!(err.is_validation_error());
225 }
226
227 #[test]
228 fn test_error_codes() {
229 assert_eq!(EmbeddedError::AllocationFailed.error_code(), 1);
230 assert_eq!(EmbeddedError::PoolExhausted.error_code(), 2);
231 assert_eq!(EmbeddedError::TargetSpecific(42).error_code(), 100);
232 }
233}