rmpv/decode/
mod.rs

1use std::error;
2use std::fmt::{self, Display, Formatter};
3use std::io::{self, ErrorKind};
4
5use rmp::decode::{MarkerReadError, ValueReadError};
6
7pub mod value;
8pub mod value_ref;
9
10pub use self::value::{read_value, read_value_with_max_depth};
11pub use self::value_ref::{read_value_ref, read_value_ref_with_max_depth};
12
13/// The maximum recursion depth before [`Error::DepthLimitExceeded`] is returned.
14pub const MAX_DEPTH: usize = 1024;
15
16/// This type represents all possible errors that can occur when deserializing a value.
17#[derive(Debug)]
18pub enum Error {
19    /// Error while reading marker byte.
20    InvalidMarkerRead(io::Error),
21    /// Error while reading data.
22    InvalidDataRead(io::Error),
23    /// The depth limit [`MAX_DEPTH`] was exceeded.
24    DepthLimitExceeded,
25}
26
27#[inline]
28fn decrement_depth(depth: u16) -> Result<u16, Error> {
29    depth.checked_sub(1).ok_or(Error::DepthLimitExceeded)
30}
31
32impl Error {
33    #[cold]
34    #[must_use] pub fn kind(&self) -> ErrorKind {
35        match *self {
36            Error::InvalidMarkerRead(ref err) => err.kind(),
37            Error::InvalidDataRead(ref err) => err.kind(),
38            Error::DepthLimitExceeded => ErrorKind::Unsupported,
39        }
40    }
41}
42
43impl error::Error for Error {
44    #[cold]
45    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
46        match *self {
47            Error::InvalidMarkerRead(ref err) => Some(err),
48            Error::InvalidDataRead(ref err) => Some(err),
49            Error::DepthLimitExceeded => None,
50        }
51    }
52}
53
54impl Display for Error {
55    #[cold]
56    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), fmt::Error> {
57        match *self {
58            Error::InvalidMarkerRead(ref err) => {
59                write!(fmt, "I/O error while reading marker byte: {err}")
60            }
61            Error::InvalidDataRead(ref err) => {
62                write!(fmt, "I/O error while reading non-marker bytes: {err}")
63            }
64            Error::DepthLimitExceeded => {
65                write!(fmt, "depth limit exceeded")
66            }
67        }
68    }
69}
70
71impl From<MarkerReadError> for Error {
72    #[cold]
73    fn from(err: MarkerReadError) -> Error {
74        Error::InvalidMarkerRead(err.0)
75    }
76}
77
78impl From<ValueReadError> for Error {
79    #[cold]
80    fn from(err: ValueReadError) -> Error {
81        match err {
82            ValueReadError::InvalidMarkerRead(err) => Error::InvalidMarkerRead(err),
83            ValueReadError::InvalidDataRead(err) => Error::InvalidDataRead(err),
84            ValueReadError::TypeMismatch(..) => {
85                Error::InvalidMarkerRead(io::Error::new(ErrorKind::Other, "type mismatch"))
86            }
87        }
88    }
89}
90
91impl From<Error> for io::Error {
92    #[cold]
93    fn from(val: Error) -> Self {
94        match val {
95            Error::InvalidMarkerRead(err) |
96            Error::InvalidDataRead(err) => err,
97            Error::DepthLimitExceeded => io::Error::new(val.kind(), val),
98        }
99    }
100}