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