1use core::convert::Infallible;
9use core::fmt;
10
11use internals::write_err;
12
13#[cfg(doc)]
14use crate::{ArrayDecoder, Decoder2, Decoder3, Decoder4, Decoder6};
15#[cfg(feature = "alloc")]
16#[cfg(doc)]
17use crate::{ByteVecDecoder, VecDecoder};
18
19#[cfg(feature = "std")]
21#[derive(Debug)]
22pub enum ReadError<D> {
23 Io(std::io::Error),
25 Decode(D),
27}
28
29#[cfg(feature = "std")]
30impl<D: core::fmt::Display> core::fmt::Display for ReadError<D> {
31 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
32 match self {
33 Self::Io(e) => write!(f, "I/O error: {}", e),
34 Self::Decode(e) => write!(f, "decode error: {}", e),
35 }
36 }
37}
38
39#[cfg(feature = "std")]
40impl<D> std::error::Error for ReadError<D>
41where
42 D: std::error::Error + 'static,
43{
44 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
45 match self {
46 Self::Io(e) => Some(e),
47 Self::Decode(e) => Some(e),
48 }
49 }
50}
51
52#[cfg(feature = "std")]
53impl<D> From<std::io::Error> for ReadError<D> {
54 fn from(e: std::io::Error) -> Self { Self::Io(e) }
55}
56
57#[derive(Debug, Clone, Eq, PartialEq)]
59pub enum DecodeError<Err> {
60 Parse(Err),
62 Unconsumed(UnconsumedError),
64}
65
66impl<Err> From<Infallible> for DecodeError<Err> {
67 fn from(never: Infallible) -> Self { match never {} }
68}
69
70impl<Err> fmt::Display for DecodeError<Err>
71where
72 Err: fmt::Display,
73{
74 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
75 match self {
76 Self::Parse(ref e) => write_err!(f, "error parsing encoded object"; e),
77 Self::Unconsumed(ref e) => write_err!(f, "unconsumed"; e),
78 }
79 }
80}
81
82#[cfg(feature = "std")]
83impl<Err> std::error::Error for DecodeError<Err>
84where
85 Err: std::error::Error + 'static,
86{
87 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
88 match self {
89 Self::Parse(ref e) => Some(e),
90 Self::Unconsumed(ref e) => Some(e),
91 }
92 }
93}
94
95#[derive(Debug, Clone, Eq, PartialEq)]
99pub struct UnconsumedError();
100
101impl From<Infallible> for UnconsumedError {
102 fn from(never: Infallible) -> Self { match never {} }
103}
104
105impl fmt::Display for UnconsumedError {
106 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
107 write!(f, "data not consumed entirely when decoding")
108 }
109}
110
111#[cfg(feature = "std")]
112impl std::error::Error for UnconsumedError {
113 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
114 let Self() = self;
115 None
116 }
117}
118
119#[derive(Debug, Clone, PartialEq, Eq)]
121pub struct CompactSizeDecoderError(pub(crate) CompactSizeDecoderErrorInner);
122
123#[derive(Debug, Clone, PartialEq, Eq)]
124pub(crate) enum CompactSizeDecoderErrorInner {
125 UnexpectedEof {
127 required: usize,
129 received: usize,
131 },
132 NonMinimal {
134 value: u64,
136 },
137 ValueExceedsLimit(LengthPrefixExceedsMaxError),
139}
140
141impl From<Infallible> for CompactSizeDecoderError {
142 fn from(never: Infallible) -> Self { match never {} }
143}
144
145impl core::fmt::Display for CompactSizeDecoderError {
146 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
147 use CompactSizeDecoderErrorInner as E;
148
149 match self.0 {
150 E::UnexpectedEof { required: 1, received: 0 } => {
151 write!(f, "required at least one byte but the input is empty")
152 }
153 E::UnexpectedEof { required, received: 0 } => {
154 write!(f, "required at least {} bytes but the input is empty", required)
155 }
156 E::UnexpectedEof { required, received } => write!(
157 f,
158 "required at least {} bytes but only {} bytes were received",
159 required, received
160 ),
161 E::NonMinimal { value } => write!(f, "the value {} was not encoded minimally", value),
162 E::ValueExceedsLimit(ref e) => write_err!(f, "value exceeds limit"; e),
163 }
164 }
165}
166
167#[cfg(feature = "std")]
168impl std::error::Error for CompactSizeDecoderError {
169 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
170 use CompactSizeDecoderErrorInner as E;
171
172 match self {
173 Self(E::ValueExceedsLimit(ref e)) => Some(e),
174 _ => None,
175 }
176 }
177}
178
179#[derive(Debug, Clone, PartialEq, Eq)]
181pub struct LengthPrefixExceedsMaxError {
182 pub(crate) limit: usize,
184 pub(crate) value: u64,
186}
187
188impl From<Infallible> for LengthPrefixExceedsMaxError {
189 fn from(never: Infallible) -> Self { match never {} }
190}
191
192impl core::fmt::Display for LengthPrefixExceedsMaxError {
193 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
194 write!(f, "decoded length {} exceeds maximum allowed {}", self.value, self.limit)
195 }
196}
197
198#[cfg(feature = "std")]
199impl std::error::Error for LengthPrefixExceedsMaxError {
200 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
201 let Self { limit: _, value: _ } = self;
202 None
203 }
204}
205
206#[cfg(feature = "alloc")]
208#[derive(Debug, Clone, PartialEq, Eq)]
209pub struct ByteVecDecoderError(pub(crate) ByteVecDecoderErrorInner);
210
211#[cfg(feature = "alloc")]
212#[derive(Debug, Clone, PartialEq, Eq)]
213pub(crate) enum ByteVecDecoderErrorInner {
214 LengthPrefixDecode(CompactSizeDecoderError),
216 UnexpectedEof(UnexpectedEofError),
218}
219
220#[cfg(feature = "alloc")]
221impl From<Infallible> for ByteVecDecoderError {
222 fn from(never: Infallible) -> Self { match never {} }
223}
224
225#[cfg(feature = "alloc")]
226impl fmt::Display for ByteVecDecoderError {
227 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
228 use ByteVecDecoderErrorInner as E;
229
230 match self.0 {
231 E::LengthPrefixDecode(ref e) => write_err!(f, "byte vec decoder error"; e),
232 E::UnexpectedEof(ref e) => write_err!(f, "byte vec decoder error"; e),
233 }
234 }
235}
236
237#[cfg(feature = "alloc")]
238#[cfg(feature = "std")]
239impl std::error::Error for ByteVecDecoderError {
240 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
241 use ByteVecDecoderErrorInner as E;
242
243 match self.0 {
244 E::LengthPrefixDecode(ref e) => Some(e),
245 E::UnexpectedEof(ref e) => Some(e),
246 }
247 }
248}
249
250#[cfg(feature = "alloc")]
252#[derive(Debug, Clone, PartialEq, Eq)]
253pub struct VecDecoderError<Err>(pub(crate) VecDecoderErrorInner<Err>);
254
255#[cfg(feature = "alloc")]
256#[derive(Debug, Clone, PartialEq, Eq)]
257pub(crate) enum VecDecoderErrorInner<Err> {
258 LengthPrefixDecode(CompactSizeDecoderError),
260 Item(Err),
262 UnexpectedEof(UnexpectedEofError),
264}
265
266#[cfg(feature = "alloc")]
267impl<Err> From<Infallible> for VecDecoderError<Err> {
268 fn from(never: Infallible) -> Self { match never {} }
269}
270
271#[cfg(feature = "alloc")]
272impl<Err> fmt::Display for VecDecoderError<Err>
273where
274 Err: fmt::Display + fmt::Debug,
275{
276 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
277 use VecDecoderErrorInner as E;
278
279 match self.0 {
280 E::LengthPrefixDecode(ref e) => write_err!(f, "vec decoder error"; e),
281 E::Item(ref e) => write_err!(f, "vec decoder error"; e),
282 E::UnexpectedEof(ref e) => write_err!(f, "vec decoder error"; e),
283 }
284 }
285}
286
287#[cfg(feature = "std")]
288impl<Err> std::error::Error for VecDecoderError<Err>
289where
290 Err: std::error::Error + 'static,
291{
292 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
293 use VecDecoderErrorInner as E;
294
295 match self.0 {
296 E::LengthPrefixDecode(ref e) => Some(e),
297 E::Item(ref e) => Some(e),
298 E::UnexpectedEof(ref e) => Some(e),
299 }
300 }
301}
302
303#[derive(Debug, Clone, PartialEq, Eq)]
305pub struct UnexpectedEofError {
306 pub(crate) missing: usize,
308}
309
310impl From<Infallible> for UnexpectedEofError {
311 fn from(never: Infallible) -> Self { match never {} }
312}
313
314impl fmt::Display for UnexpectedEofError {
315 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
316 write!(f, "not enough bytes for decoder, {} more bytes required", self.missing)
317 }
318}
319
320#[cfg(feature = "std")]
321impl std::error::Error for UnexpectedEofError {
322 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
323 let Self { missing: _ } = self;
324 None
325 }
326}
327
328#[cfg(feature = "hex")]
330#[derive(Debug, Clone, PartialEq, Eq)]
331pub struct FromHexError<ParseErr>(pub(crate) FromHexErrorInner<ParseErr>);
332
333#[cfg(feature = "hex")]
334#[derive(Debug, Clone, PartialEq, Eq)]
335pub(crate) enum FromHexErrorInner<ParseErr> {
336 OddLength(hex::OddLengthStringError),
338 InvalidChar(hex::InvalidCharError),
340 Decode(DecodeError<ParseErr>),
342}
343
344#[cfg(feature = "hex")]
345impl<ParseErr> From<Infallible> for FromHexError<ParseErr> {
346 fn from(never: Infallible) -> Self { match never {} }
347}
348
349#[cfg(feature = "hex")]
350impl<ParseErr: fmt::Display> fmt::Display for FromHexError<ParseErr> {
351 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
352 match self.0 {
353 FromHexErrorInner::OddLength(ref e) => write_err!(f, "odd length string"; e),
354 FromHexErrorInner::InvalidChar(ref e) => write_err!(f, "invalid character"; e),
355 FromHexErrorInner::Decode(ref e) => write_err!(f, "decode error"; e),
356 }
357 }
358}
359
360#[cfg(feature = "hex")]
361#[cfg(feature = "std")]
362impl<ParseErr> std::error::Error for FromHexError<ParseErr>
363where
364 ParseErr: std::error::Error + 'static,
365{
366 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
367 match self.0 {
368 FromHexErrorInner::OddLength(ref e) => Some(e),
369 FromHexErrorInner::InvalidChar(ref e) => Some(e),
370 FromHexErrorInner::Decode(ref e) => Some(e),
371 }
372 }
373}
374
375macro_rules! define_decoder_n_error {
377 (
378 $(#[$attr:meta])*
379 $name:ident;
380 $(
381 $(#[$err_attr:meta])*
382 ($err_wrap:ident, $err_type:ident, $err_msg:literal),
383 )*
384 ) => {
385 $(#[$attr])*
386 #[derive(Debug, Clone, PartialEq, Eq)]
387 pub enum $name<$($err_type,)*> {
388 $(
389 $(#[$err_attr])*
390 $err_wrap($err_type),
391 )*
392 }
393
394 impl<$($err_type,)*> fmt::Display for $name<$($err_type,)*>
395 where
396 $($err_type: fmt::Display,)*
397 {
398 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
399 match self {
400 $(Self::$err_wrap(ref e) => write_err!(f, $err_msg; e),)*
401 }
402 }
403 }
404
405 #[cfg(feature = "std")]
406 impl<$($err_type,)*> std::error::Error for $name<$($err_type,)*>
407 where
408 $($err_type: std::error::Error + 'static,)*
409 {
410 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
411 match self {
412 $(Self::$err_wrap(ref e) => Some(e),)*
413 }
414 }
415 }
416 };
417}
418
419define_decoder_n_error! {
420 Decoder2Error;
422 (First, A, "first decoder error."),
424 (Second, B, "second decoder error."),
426}
427
428define_decoder_n_error! {
429 Decoder3Error;
431 (First, A, "first decoder error."),
433 (Second, B, "second decoder error."),
435 (Third, C, "third decoder error."),
437}
438
439define_decoder_n_error! {
440 Decoder4Error;
442 (First, A, "first decoder error."),
444 (Second, B, "second decoder error."),
446 (Third, C, "third decoder error."),
448 (Fourth, D, "fourth decoder error."),
450}
451
452define_decoder_n_error! {
453 Decoder6Error;
455 (First, A, "first decoder error."),
457 (Second, B, "second decoder error."),
459 (Third, C, "third decoder error."),
461 (Fourth, D, "fourth decoder error."),
463 (Fifth, E, "fifth decoder error."),
465 (Sixth, F, "sixth decoder error."),
467}