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)> { None }
114}
115
116#[derive(Debug, Clone, PartialEq, Eq)]
118pub struct CompactSizeDecoderError(pub(crate) CompactSizeDecoderErrorInner);
119
120#[derive(Debug, Clone, PartialEq, Eq)]
121pub(crate) enum CompactSizeDecoderErrorInner {
122 UnexpectedEof {
124 required: usize,
126 received: usize,
128 },
129 NonMinimal {
131 value: u64,
133 },
134 ValueExceedsLimit(LengthPrefixExceedsMaxError),
136}
137
138impl From<Infallible> for CompactSizeDecoderError {
139 fn from(never: Infallible) -> Self { match never {} }
140}
141
142impl core::fmt::Display for CompactSizeDecoderError {
143 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
144 use CompactSizeDecoderErrorInner as E;
145
146 match self.0 {
147 E::UnexpectedEof { required: 1, received: 0 } => {
148 write!(f, "required at least one byte but the input is empty")
149 }
150 E::UnexpectedEof { required, received: 0 } => {
151 write!(f, "required at least {} bytes but the input is empty", required)
152 }
153 E::UnexpectedEof { required, received } => write!(
154 f,
155 "required at least {} bytes but only {} bytes were received",
156 required, received
157 ),
158 E::NonMinimal { value } => write!(f, "the value {} was not encoded minimally", value),
159 E::ValueExceedsLimit(ref e) => write_err!(f, "value exceeds limit"; e),
160 }
161 }
162}
163
164#[cfg(feature = "std")]
165impl std::error::Error for CompactSizeDecoderError {
166 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
167 use CompactSizeDecoderErrorInner as E;
168
169 match self {
170 Self(E::ValueExceedsLimit(ref e)) => Some(e),
171 _ => None,
172 }
173 }
174}
175
176#[derive(Debug, Clone, PartialEq, Eq)]
178pub struct LengthPrefixExceedsMaxError {
179 pub(crate) limit: usize,
181 pub(crate) value: u64,
183}
184
185impl From<Infallible> for LengthPrefixExceedsMaxError {
186 fn from(never: Infallible) -> Self { match never {} }
187}
188
189impl core::fmt::Display for LengthPrefixExceedsMaxError {
190 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
191 write!(f, "decoded length {} exceeds maximum allowed {}", self.value, self.limit)
192 }
193}
194
195#[cfg(feature = "std")]
196impl std::error::Error for LengthPrefixExceedsMaxError {
197 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
198}
199
200#[cfg(feature = "alloc")]
202#[derive(Debug, Clone, PartialEq, Eq)]
203pub struct ByteVecDecoderError(pub(crate) ByteVecDecoderErrorInner);
204
205#[cfg(feature = "alloc")]
206#[derive(Debug, Clone, PartialEq, Eq)]
207pub(crate) enum ByteVecDecoderErrorInner {
208 LengthPrefixDecode(CompactSizeDecoderError),
210 UnexpectedEof(UnexpectedEofError),
212}
213
214#[cfg(feature = "alloc")]
215impl From<Infallible> for ByteVecDecoderError {
216 fn from(never: Infallible) -> Self { match never {} }
217}
218
219#[cfg(feature = "alloc")]
220impl fmt::Display for ByteVecDecoderError {
221 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
222 use ByteVecDecoderErrorInner as E;
223
224 match self.0 {
225 E::LengthPrefixDecode(ref e) => write_err!(f, "byte vec decoder error"; e),
226 E::UnexpectedEof(ref e) => write_err!(f, "byte vec decoder error"; e),
227 }
228 }
229}
230
231#[cfg(feature = "alloc")]
232#[cfg(feature = "std")]
233impl std::error::Error for ByteVecDecoderError {
234 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
235 use ByteVecDecoderErrorInner as E;
236
237 match self.0 {
238 E::LengthPrefixDecode(ref e) => Some(e),
239 E::UnexpectedEof(ref e) => Some(e),
240 }
241 }
242}
243
244#[cfg(feature = "alloc")]
246#[derive(Debug, Clone, PartialEq, Eq)]
247pub struct VecDecoderError<Err>(pub(crate) VecDecoderErrorInner<Err>);
248
249#[cfg(feature = "alloc")]
250#[derive(Debug, Clone, PartialEq, Eq)]
251pub(crate) enum VecDecoderErrorInner<Err> {
252 LengthPrefixDecode(CompactSizeDecoderError),
254 Item(Err),
256 UnexpectedEof(UnexpectedEofError),
258}
259
260#[cfg(feature = "alloc")]
261impl<Err> From<Infallible> for VecDecoderError<Err> {
262 fn from(never: Infallible) -> Self { match never {} }
263}
264
265#[cfg(feature = "alloc")]
266impl<Err> fmt::Display for VecDecoderError<Err>
267where
268 Err: fmt::Display + fmt::Debug,
269{
270 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
271 use VecDecoderErrorInner as E;
272
273 match self.0 {
274 E::LengthPrefixDecode(ref e) => write_err!(f, "vec decoder error"; e),
275 E::Item(ref e) => write_err!(f, "vec decoder error"; e),
276 E::UnexpectedEof(ref e) => write_err!(f, "vec decoder error"; e),
277 }
278 }
279}
280
281#[cfg(feature = "std")]
282impl<Err> std::error::Error for VecDecoderError<Err>
283where
284 Err: std::error::Error + 'static,
285{
286 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
287 use VecDecoderErrorInner as E;
288
289 match self.0 {
290 E::LengthPrefixDecode(ref e) => Some(e),
291 E::Item(ref e) => Some(e),
292 E::UnexpectedEof(ref e) => Some(e),
293 }
294 }
295}
296
297#[derive(Debug, Clone, PartialEq, Eq)]
299pub struct UnexpectedEofError {
300 pub(crate) missing: usize,
302}
303
304impl From<Infallible> for UnexpectedEofError {
305 fn from(never: Infallible) -> Self { match never {} }
306}
307
308impl fmt::Display for UnexpectedEofError {
309 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
310 write!(f, "not enough bytes for decoder, {} more bytes required", self.missing)
311 }
312}
313
314#[cfg(feature = "std")]
315impl std::error::Error for UnexpectedEofError {
316 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
317}
318
319macro_rules! define_decoder_n_error {
321 (
322 $(#[$attr:meta])*
323 $name:ident;
324 $(
325 $(#[$err_attr:meta])*
326 ($err_wrap:ident, $err_type:ident, $err_msg:literal),
327 )*
328 ) => {
329 $(#[$attr])*
330 #[derive(Debug, Clone, PartialEq, Eq)]
331 pub enum $name<$($err_type,)*> {
332 $(
333 $(#[$err_attr])*
334 $err_wrap($err_type),
335 )*
336 }
337
338 impl<$($err_type,)*> fmt::Display for $name<$($err_type,)*>
339 where
340 $($err_type: fmt::Display,)*
341 {
342 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
343 match self {
344 $(Self::$err_wrap(ref e) => write_err!(f, $err_msg; e),)*
345 }
346 }
347 }
348
349 #[cfg(feature = "std")]
350 impl<$($err_type,)*> std::error::Error for $name<$($err_type,)*>
351 where
352 $($err_type: std::error::Error + 'static,)*
353 {
354 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
355 match self {
356 $(Self::$err_wrap(ref e) => Some(e),)*
357 }
358 }
359 }
360 };
361}
362
363define_decoder_n_error! {
364 Decoder2Error;
366 (First, A, "first decoder error."),
368 (Second, B, "second decoder error."),
370}
371
372define_decoder_n_error! {
373 Decoder3Error;
375 (First, A, "first decoder error."),
377 (Second, B, "second decoder error."),
379 (Third, C, "third decoder error."),
381}
382
383define_decoder_n_error! {
384 Decoder4Error;
386 (First, A, "first decoder error."),
388 (Second, B, "second decoder error."),
390 (Third, C, "third decoder error."),
392 (Fourth, D, "fourth decoder error."),
394}
395
396define_decoder_n_error! {
397 Decoder6Error;
399 (First, A, "first decoder error."),
401 (Second, B, "second decoder error."),
403 (Third, C, "third decoder error."),
405 (Fourth, D, "fourth decoder error."),
407 (Fifth, E, "fifth decoder error."),
409 (Sixth, F, "sixth decoder error."),
411}