Skip to main content

cbor_core/
error.rs

1use std::{fmt, io};
2
3/// Errors produced during CBOR encoding, decoding, or value access.
4#[derive(Debug)]
5#[non_exhaustive]
6pub enum Error {
7    /// Accessor called on a value of the wrong CBOR type.
8    IncompatibleType,
9    /// Integer does not fit in the target type.
10    Overflow,
11    /// Attempted to read a negative integer as an unsigned type.
12    NegativeUnsigned,
13    /// Float conversion would lose precision.
14    Precision,
15    /// Simple value number is in the reserved range 24-31.
16    InvalidSimpleValue,
17
18    /// CBOR input is not in canonical (deterministic) form.
19    InvalidEncoding,
20    /// Text string contains invalid UTF-8.
21    InvalidUtf8,
22    /// Input ended before a complete data item was read.
23    UnexpectedEof,
24    /// Declared length exceeds addressable memory.
25    LengthTooLarge,
26
27    /// Underlying I/O error.
28    Io(io::Error),
29}
30
31impl fmt::Display for Error {
32    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33        match self {
34            Self::IncompatibleType => write!(f, "incompatible CBOR type"),
35            Self::Overflow => write!(f, "integer overflow"),
36            Self::NegativeUnsigned => write!(f, "negative value for unsigned type"),
37            Self::Precision => write!(f, "precision loss"),
38            Self::InvalidSimpleValue => write!(f, "invalid CBOR simple value"),
39            Self::InvalidEncoding => write!(f, "invalid CBOR encoding"),
40            Self::InvalidUtf8 => write!(f, "invalid UTF-8 in CBOR text string"),
41            Self::UnexpectedEof => write!(f, "unexpected end of CBOR input"),
42            Self::LengthTooLarge => write!(f, "CBOR length exceeds addressable memory"),
43            Self::Io(err) => write!(f, "I/O error: {err}"),
44        }
45    }
46}
47
48impl std::error::Error for Error {
49    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
50        match self {
51            Self::Io(err) => Some(err),
52            _ => None,
53        }
54    }
55}
56
57impl From<io::Error> for Error {
58    fn from(err: io::Error) -> Self {
59        Self::Io(err)
60    }
61}
62
63impl From<Error> for io::Error {
64    fn from(err: Error) -> Self {
65        match err {
66            Error::Io(io_err) => io_err,
67            other => io::Error::new(io::ErrorKind::InvalidData, other),
68        }
69    }
70}
71
72impl PartialEq for Error {
73    fn eq(&self, other: &Self) -> bool {
74        matches!(
75            (self, other),
76            (Self::IncompatibleType, Self::IncompatibleType)
77                | (Self::Overflow, Self::Overflow)
78                | (Self::NegativeUnsigned, Self::NegativeUnsigned)
79                | (Self::Precision, Self::Precision)
80                | (Self::InvalidSimpleValue, Self::InvalidSimpleValue)
81                | (Self::InvalidEncoding, Self::InvalidEncoding)
82                | (Self::InvalidUtf8, Self::InvalidUtf8)
83                | (Self::UnexpectedEof, Self::UnexpectedEof)
84                | (Self::LengthTooLarge, Self::LengthTooLarge)
85                | _
86        )
87    }
88}
89
90impl Eq for Error {}
91
92/// Convenience alias used throughout this crate.
93pub type Result<T> = std::result::Result<T, Error>;