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
13pub const MAX_DEPTH: usize = 1024;
15
16#[derive(Debug)]
18pub enum Error {
19 InvalidMarkerRead(io::Error),
21 InvalidDataRead(io::Error),
23 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}