Skip to main content

tidecoin_consensus_encoding/
error.rs

1// SPDX-License-Identifier: CC0-1.0
2
3//! Error types for the whole crate.
4//!
5//! All error types are publicly available at the crate root.
6// We separate them into a module so the HTML docs are less cluttered.
7
8use 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/// An error that can occur when reading and decoding from a buffered reader.
20#[cfg(feature = "std")]
21#[derive(Debug)]
22pub enum ReadError<D> {
23    /// An I/O error occurred while reading from the reader.
24    Io(std::io::Error),
25    /// The decoder encountered an error while parsing the data.
26    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 {
55        Self::Io(e)
56    }
57}
58
59/// An error that can occur when decoding from a byte slice.
60#[derive(Debug, Clone, Eq, PartialEq)]
61pub enum DecodeError<Err> {
62    /// Provided slice failed to correctly decode as a type.
63    Parse(Err),
64    /// Bytes remained unconsumed after completing decoding.
65    Unconsumed(UnconsumedError),
66}
67
68impl<Err> From<Infallible> for DecodeError<Err> {
69    fn from(never: Infallible) -> Self {
70        match never {}
71    }
72}
73
74impl<Err> fmt::Display for DecodeError<Err>
75where
76    Err: fmt::Display,
77{
78    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
79        match self {
80            Self::Parse(ref e) => write_err!(f, "error parsing encoded object"; e),
81            Self::Unconsumed(ref e) => write_err!(f, "unconsumed"; e),
82        }
83    }
84}
85
86#[cfg(feature = "std")]
87impl<Err> std::error::Error for DecodeError<Err>
88where
89    Err: std::error::Error + 'static,
90{
91    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
92        match self {
93            Self::Parse(ref e) => Some(e),
94            Self::Unconsumed(ref e) => Some(e),
95        }
96    }
97}
98
99/// Bytes remained unconsumed after completing decoding.
100// This is just to give us the ability to add details in a
101// non-breaking way if we want to at some stage.
102#[derive(Debug, Clone, Eq, PartialEq)]
103pub struct UnconsumedError();
104
105impl From<Infallible> for UnconsumedError {
106    fn from(never: Infallible) -> Self {
107        match never {}
108    }
109}
110
111impl fmt::Display for UnconsumedError {
112    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
113        write!(f, "data not consumed entirely when decoding")
114    }
115}
116
117#[cfg(feature = "std")]
118impl std::error::Error for UnconsumedError {
119    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
120        None
121    }
122}
123
124/// An error consensus decoding a compact size encoded integer.
125#[derive(Debug, Clone, PartialEq, Eq)]
126pub struct CompactSizeDecoderError(pub(crate) CompactSizeDecoderErrorInner);
127
128#[derive(Debug, Clone, PartialEq, Eq)]
129pub(crate) enum CompactSizeDecoderErrorInner {
130    /// Returned when the decoder reaches end of stream (EOF).
131    UnexpectedEof {
132        /// How many bytes were required.
133        required: usize,
134        /// How many bytes were received.
135        received: usize,
136    },
137    /// Returned when the encoding is not minimal
138    NonMinimal {
139        /// The encoded value.
140        value: u64,
141    },
142    /// Returned when the encoded value exceeds the decoder's limit.
143    ValueExceedsLimit(LengthPrefixExceedsMaxError),
144}
145
146impl From<Infallible> for CompactSizeDecoderError {
147    fn from(never: Infallible) -> Self {
148        match never {}
149    }
150}
151
152impl core::fmt::Display for CompactSizeDecoderError {
153    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
154        use internals::write_err;
155        use CompactSizeDecoderErrorInner as E;
156
157        match self.0 {
158            E::UnexpectedEof { required: 1, received: 0 } => {
159                write!(f, "required at least one byte but the input is empty")
160            }
161            E::UnexpectedEof { required, received: 0 } => {
162                write!(f, "required at least {} bytes but the input is empty", required)
163            }
164            E::UnexpectedEof { required, received } => write!(
165                f,
166                "required at least {} bytes but only {} bytes were received",
167                required, received
168            ),
169            E::NonMinimal { value } => write!(f, "the value {} was not encoded minimally", value),
170            E::ValueExceedsLimit(ref e) => write_err!(f, "value exceeds limit"; e),
171        }
172    }
173}
174
175#[cfg(feature = "std")]
176impl std::error::Error for CompactSizeDecoderError {
177    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
178        use CompactSizeDecoderErrorInner as E;
179
180        match self {
181            Self(E::ValueExceedsLimit(ref e)) => Some(e),
182            _ => None,
183        }
184    }
185}
186
187/// The error returned when a compact size value exceeds a configured limit.
188#[derive(Debug, Clone, PartialEq, Eq)]
189pub struct LengthPrefixExceedsMaxError {
190    /// The limit that was exceeded.
191    pub(crate) limit: usize,
192    /// The value that exceeded the limit.
193    pub(crate) value: u64,
194}
195
196impl From<Infallible> for LengthPrefixExceedsMaxError {
197    fn from(never: Infallible) -> Self {
198        match never {}
199    }
200}
201
202impl core::fmt::Display for LengthPrefixExceedsMaxError {
203    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
204        write!(f, "decoded length {} exceeds maximum allowed {}", self.value, self.limit)
205    }
206}
207
208#[cfg(feature = "std")]
209impl std::error::Error for LengthPrefixExceedsMaxError {}
210
211/// The error returned by the [`ByteVecDecoder`].
212#[cfg(feature = "alloc")]
213#[derive(Debug, Clone, PartialEq, Eq)]
214pub struct ByteVecDecoderError(pub(crate) ByteVecDecoderErrorInner);
215
216#[cfg(feature = "alloc")]
217#[derive(Debug, Clone, PartialEq, Eq)]
218pub(crate) enum ByteVecDecoderErrorInner {
219    /// Error decoding the byte vector length prefix.
220    LengthPrefixDecode(CompactSizeDecoderError),
221    /// Not enough bytes given to decoder.
222    UnexpectedEof(UnexpectedEofError),
223}
224
225#[cfg(feature = "alloc")]
226impl From<Infallible> for ByteVecDecoderError {
227    fn from(never: Infallible) -> Self {
228        match never {}
229    }
230}
231
232#[cfg(feature = "alloc")]
233impl fmt::Display for ByteVecDecoderError {
234    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
235        use ByteVecDecoderErrorInner as E;
236
237        match self.0 {
238            E::LengthPrefixDecode(ref e) => write_err!(f, "byte vec decoder error"; e),
239            E::UnexpectedEof(ref e) => write_err!(f, "byte vec decoder error"; e),
240        }
241    }
242}
243
244#[cfg(all(feature = "std", feature = "alloc"))]
245impl std::error::Error for ByteVecDecoderError {
246    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
247        use ByteVecDecoderErrorInner as E;
248
249        match self.0 {
250            E::LengthPrefixDecode(ref e) => Some(e),
251            E::UnexpectedEof(ref e) => Some(e),
252        }
253    }
254}
255
256/// The error returned by the [`VecDecoder`].
257#[cfg(feature = "alloc")]
258#[derive(Debug, Clone, PartialEq, Eq)]
259pub struct VecDecoderError<Err>(pub(crate) VecDecoderErrorInner<Err>);
260
261#[cfg(feature = "alloc")]
262#[derive(Debug, Clone, PartialEq, Eq)]
263pub(crate) enum VecDecoderErrorInner<Err> {
264    /// Error decoding the vector length prefix.
265    LengthPrefixDecode(CompactSizeDecoderError),
266    /// Error while decoding an item.
267    Item(Err),
268    /// Not enough bytes given to decoder.
269    UnexpectedEof(UnexpectedEofError),
270}
271
272#[cfg(feature = "alloc")]
273impl<Err> From<Infallible> for VecDecoderError<Err> {
274    fn from(never: Infallible) -> Self {
275        match never {}
276    }
277}
278
279#[cfg(feature = "alloc")]
280impl<Err> fmt::Display for VecDecoderError<Err>
281where
282    Err: fmt::Display + fmt::Debug,
283{
284    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
285        use VecDecoderErrorInner as E;
286
287        match self.0 {
288            E::LengthPrefixDecode(ref e) => write_err!(f, "vec decoder error"; e),
289            E::Item(ref e) => write_err!(f, "vec decoder error"; e),
290            E::UnexpectedEof(ref e) => write_err!(f, "vec decoder error"; e),
291        }
292    }
293}
294
295#[cfg(feature = "std")]
296impl<Err> std::error::Error for VecDecoderError<Err>
297where
298    Err: std::error::Error + 'static,
299{
300    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
301        use VecDecoderErrorInner as E;
302
303        match self.0 {
304            E::LengthPrefixDecode(ref e) => Some(e),
305            E::Item(ref e) => Some(e),
306            E::UnexpectedEof(ref e) => Some(e),
307        }
308    }
309}
310
311/// Not enough bytes given to decoder.
312#[derive(Debug, Clone, PartialEq, Eq)]
313pub struct UnexpectedEofError {
314    /// Number of bytes missing to complete decoder.
315    pub(crate) missing: usize,
316}
317
318impl From<Infallible> for UnexpectedEofError {
319    fn from(never: Infallible) -> Self {
320        match never {}
321    }
322}
323
324impl fmt::Display for UnexpectedEofError {
325    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
326        write!(f, "not enough bytes for decoder, {} more bytes required", self.missing)
327    }
328}
329
330#[cfg(feature = "std")]
331impl std::error::Error for UnexpectedEofError {}
332
333/// Helper macro to define an error type for a `DecoderN`.
334macro_rules! define_decoder_n_error {
335    (
336        $(#[$attr:meta])*
337        $name:ident;
338        $(
339            $(#[$err_attr:meta])*
340            ($err_wrap:ident, $err_type:ident, $err_msg:literal),
341        )*
342    ) => {
343        $(#[$attr])*
344        #[derive(Debug, Clone, PartialEq, Eq)]
345        pub enum $name<$($err_type,)*> {
346            $(
347                $(#[$err_attr])*
348                $err_wrap($err_type),
349            )*
350        }
351
352        impl<$($err_type,)*> fmt::Display for $name<$($err_type,)*>
353        where
354            $($err_type: fmt::Display,)*
355        {
356            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
357                match self {
358                    $(Self::$err_wrap(ref e) => write_err!(f, $err_msg; e),)*
359                }
360            }
361        }
362
363        #[cfg(feature = "std")]
364        impl<$($err_type,)*> std::error::Error for $name<$($err_type,)*>
365        where
366            $($err_type: std::error::Error + 'static,)*
367        {
368            fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
369                match self {
370                    $(Self::$err_wrap(ref e) => Some(e),)*
371                }
372            }
373        }
374    };
375}
376
377define_decoder_n_error! {
378    /// Error type for [`Decoder2`].
379    Decoder2Error;
380    /// Error from the first decoder.
381    (First, A, "first decoder error."),
382    /// Error from the second decoder.
383    (Second, B, "second decoder error."),
384}
385
386define_decoder_n_error! {
387    /// Error type for [`Decoder3`].
388    Decoder3Error;
389    /// Error from the first decoder.
390    (First, A, "first decoder error."),
391    /// Error from the second decoder.
392    (Second, B, "second decoder error."),
393    /// Error from the third decoder.
394    (Third, C, "third decoder error."),
395}
396
397define_decoder_n_error! {
398    /// Error type for [`Decoder4`].
399    Decoder4Error;
400    /// Error from the first decoder.
401    (First, A, "first decoder error."),
402    /// Error from the second decoder.
403    (Second, B, "second decoder error."),
404    /// Error from the third decoder.
405    (Third, C, "third decoder error."),
406    /// Error from the fourth decoder.
407    (Fourth, D, "fourth decoder error."),
408}
409
410define_decoder_n_error! {
411    /// Error type for [`Decoder6`].
412    Decoder6Error;
413    /// Error from the first decoder.
414    (First, A, "first decoder error."),
415    /// Error from the second decoder.
416    (Second, B, "second decoder error."),
417    /// Error from the third decoder.
418    (Third, C, "third decoder error."),
419    /// Error from the fourth decoder.
420    (Fourth, D, "fourth decoder error."),
421    /// Error from the fifth decoder.
422    (Fifth, E, "fifth decoder error."),
423    /// Error from the sixth decoder.
424    (Sixth, F, "sixth decoder error."),
425}