1use core::fmt;
11
12#[derive(Debug, Clone, PartialEq, Eq)]
14pub enum EncodeError {
15 BufferTooSmall {
19 needed: usize,
21 available: usize,
23 },
24 ValueOutOfRange {
27 message: &'static str,
29 },
30 MissingNonOptionalMember {
34 member_id: u32,
36 },
37}
38
39impl fmt::Display for EncodeError {
40 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41 match self {
42 Self::BufferTooSmall { needed, available } => write!(
43 f,
44 "encoder buffer too small: needed {needed} bytes, available {available}"
45 ),
46 Self::ValueOutOfRange { message } => write!(f, "value out of range: {message}"),
47 Self::MissingNonOptionalMember { member_id } => write!(
48 f,
49 "mutable struct missing non-optional member: id={member_id}"
50 ),
51 }
52 }
53}
54
55#[cfg(feature = "std")]
56impl std::error::Error for EncodeError {}
57
58#[derive(Debug, Clone, PartialEq, Eq)]
60pub enum DecodeError {
61 UnexpectedEof {
63 needed: usize,
65 offset: usize,
67 },
68 InvalidUtf8 {
70 offset: usize,
72 },
73 InvalidBool {
75 value: u8,
77 offset: usize,
79 },
80 InvalidChar {
82 value: u32,
84 offset: usize,
86 },
87 LengthExceeded {
90 announced: usize,
92 remaining: usize,
94 offset: usize,
96 },
97 InvalidString {
99 offset: usize,
101 reason: &'static str,
103 },
104 InvalidEnum {
107 kind: &'static str,
109 value: u32,
111 },
112 UnknownMustUnderstandMember {
116 member_id: u32,
118 },
119 MissingNonOptionalMember {
122 member_id: u32,
124 },
125}
126
127impl fmt::Display for DecodeError {
128 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
129 match self {
130 Self::UnexpectedEof { needed, offset } => {
131 write!(
132 f,
133 "unexpected EOF: needed {needed} more bytes at offset {offset}"
134 )
135 }
136 Self::InvalidUtf8 { offset } => write!(f, "invalid UTF-8 at offset {offset}"),
137 Self::InvalidBool { value, offset } => {
138 write!(f, "invalid bool byte 0x{value:02x} at offset {offset}")
139 }
140 Self::InvalidChar { value, offset } => {
141 write!(f, "invalid char codepoint U+{value:04X} at offset {offset}")
142 }
143 Self::LengthExceeded {
144 announced,
145 remaining,
146 offset,
147 } => write!(
148 f,
149 "length {announced} at offset {offset} exceeds remaining {remaining} bytes"
150 ),
151 Self::InvalidString { offset, reason } => {
152 write!(f, "invalid CDR string at offset {offset}: {reason}")
153 }
154 Self::InvalidEnum { kind, value } => {
155 write!(f, "invalid {kind} discriminator: {value}")
156 }
157 Self::UnknownMustUnderstandMember { member_id } => {
158 write!(f, "unknown must_understand member id: {member_id}")
159 }
160 Self::MissingNonOptionalMember { member_id } => {
161 write!(f, "missing non-optional member id: {member_id}")
162 }
163 }
164 }
165}
166
167#[cfg(feature = "std")]
168impl std::error::Error for DecodeError {}
169
170#[cfg(test)]
171mod tests {
172 use super::*;
173
174 #[cfg(feature = "alloc")]
175 extern crate alloc;
176 #[cfg(feature = "alloc")]
177 use alloc::format;
178
179 #[test]
180 fn encode_error_display_buffer_too_small() {
181 let e = EncodeError::BufferTooSmall {
182 needed: 8,
183 available: 4,
184 };
185 let s = format!("{e}");
186 assert!(s.contains("8"));
187 assert!(s.contains("4"));
188 }
189
190 #[test]
191 fn encode_error_display_value_out_of_range() {
192 let e = EncodeError::ValueOutOfRange {
193 message: "string too long",
194 };
195 assert!(format!("{e}").contains("string too long"));
196 }
197
198 #[test]
199 fn decode_error_display_unexpected_eof() {
200 let e = DecodeError::UnexpectedEof {
201 needed: 4,
202 offset: 12,
203 };
204 let s = format!("{e}");
205 assert!(s.contains("4"));
206 assert!(s.contains("12"));
207 }
208
209 #[test]
210 fn decode_error_display_invalid_utf8() {
211 let e = DecodeError::InvalidUtf8 { offset: 5 };
212 assert!(format!("{e}").contains("5"));
213 }
214
215 #[test]
216 fn decode_error_display_invalid_bool() {
217 let e = DecodeError::InvalidBool {
218 value: 0xff,
219 offset: 0,
220 };
221 assert!(format!("{e}").contains("ff"));
222 }
223
224 #[test]
225 fn decode_error_display_invalid_char() {
226 let e = DecodeError::InvalidChar {
227 value: 0xD800,
228 offset: 0,
229 };
230 assert!(format!("{e}").contains("D800"));
231 }
232
233 #[test]
234 fn decode_error_display_length_exceeded() {
235 let e = DecodeError::LengthExceeded {
236 announced: 100,
237 remaining: 4,
238 offset: 0,
239 };
240 let s = format!("{e}");
241 assert!(s.contains("100"));
242 assert!(s.contains("4"));
243 }
244
245 #[test]
246 fn errors_are_clone_eq() {
247 let e1 = EncodeError::ValueOutOfRange { message: "x" };
248 let e2 = e1.clone();
249 assert_eq!(e1, e2);
250 let d1 = DecodeError::UnexpectedEof {
251 needed: 1,
252 offset: 0,
253 };
254 assert_eq!(d1.clone(), d1);
255 }
256}