messagepack_core/decode/
mod.rs

1//! Decoding primitives for MessagePack.
2
3use crate::{Format, io::IoRead};
4
5mod array;
6pub use array::ArrayDecoder;
7mod bin;
8pub use bin::ReferenceDecoder;
9mod bool;
10mod float;
11mod int;
12mod map;
13pub use map::MapDecoder;
14mod nil;
15pub use nil::NilDecoder;
16mod str;
17pub use str::{ReferenceStr, ReferenceStrDecoder};
18mod timestamp;
19
20/// MessagePack decode error
21#[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq)]
22pub enum Error<E> {
23    /// Invalid data
24    InvalidData,
25    /// Unexpected format
26    UnexpectedFormat,
27    /// Unexpected end of data
28    UnexpectedEof,
29    /// Io error while decode format
30    Io(E),
31}
32
33impl<E> core::fmt::Display for Error<E>
34where
35    E: core::fmt::Display,
36{
37    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
38        match self {
39            Error::InvalidData => write!(f, "Cannot decode invalid data"),
40            Error::UnexpectedFormat => write!(f, "Unexpected format found"),
41            Error::UnexpectedEof => write!(f, "Unexpected end of data"),
42            Error::Io(e) => e.fmt(f),
43        }
44    }
45}
46
47impl<E> core::error::Error for Error<E>
48where
49    E: core::error::Error + 'static,
50{
51    fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
52        match self {
53            Error::Io(e) => Some(e),
54            _ => None,
55        }
56    }
57}
58
59/// Decode a value from MessagePack.
60///
61/// Returned values may borrow from the reader's buffer with lifetime
62/// `'a` (bounded by `'de`).
63pub trait Decode<'de> {
64    /// The decoded value (may borrow for `'a`).
65    type Value<'a>: Sized
66    where
67        Self: 'a,
68        'de: 'a;
69    /// Decode the next value.
70    fn decode<'a, R>(reader: &'a mut R) -> Result<Self::Value<'a>, Error<R::Error>>
71    where
72        R: IoRead<'de>,
73        'de: 'a,
74    {
75        // Avoid recursive call when `Self = Format` by decoding the marker
76        // via `DecodeBorrowed` explicitly.
77        let format = <Format as DecodeBorrowed<'de>>::decode_borrowed(reader)?;
78        Self::decode_with_format(format, reader)
79    }
80
81    /// Decode with a previously read `Format`.
82    fn decode_with_format<'a, R>(
83        format: Format,
84        reader: &'a mut R,
85    ) -> Result<Self::Value<'a>, Error<R::Error>>
86    where
87        R: IoRead<'de>,
88        'de: 'a;
89}
90
91/// Decode a value whose borrows are bounded by `'de`.
92///
93/// Implementations must not return references to the reader's transient buffer.
94pub trait DecodeBorrowed<'de> {
95    /// The decoded value.
96    type Value;
97
98    /// Decode the next value.
99    fn decode_borrowed<R>(
100        reader: &mut R,
101    ) -> Result<<Self as DecodeBorrowed<'de>>::Value, Error<R::Error>>
102    where
103        R: IoRead<'de>,
104    {
105        let format = <Format as DecodeBorrowed<'de>>::decode_borrowed(reader)?;
106        Self::decode_borrowed_with_format(format, reader)
107    }
108
109    /// Decode with a previously read `Format`.
110    fn decode_borrowed_with_format<R>(
111        format: Format,
112        reader: &mut R,
113    ) -> Result<<Self as DecodeBorrowed<'de>>::Value, Error<R::Error>>
114    where
115        R: IoRead<'de>;
116}
117
118impl<'de, T> Decode<'de> for T
119where
120    T: DecodeBorrowed<'de>,
121    T: 'de,
122{
123    type Value<'a>
124        = <T as DecodeBorrowed<'de>>::Value
125    where
126        Self: 'a,
127        'de: 'a;
128
129    fn decode_with_format<'a, R>(
130        format: Format,
131        reader: &'a mut R,
132    ) -> Result<Self::Value<'a>, Error<R::Error>>
133    where
134        R: IoRead<'de>,
135        'de: 'a,
136    {
137        <T as DecodeBorrowed<'de>>::decode_borrowed_with_format(format, reader)
138    }
139}
140
141impl<'de> DecodeBorrowed<'de> for Format {
142    type Value = Self;
143    fn decode_borrowed<R>(reader: &mut R) -> Result<Self::Value, Error<R::Error>>
144    where
145        R: IoRead<'de>,
146    {
147        let b = reader.read_slice(1).map_err(Error::Io)?;
148        let byte = match b {
149            crate::io::Reference::Borrowed(b) => b[0],
150            crate::io::Reference::Copied(b) => b[0],
151        };
152        Ok(Self::from_byte(byte))
153    }
154
155    fn decode_borrowed_with_format<R>(
156        format: Format,
157        _reader: &mut R,
158    ) -> Result<Self::Value, Error<R::Error>>
159    where
160        R: IoRead<'de>,
161    {
162        Ok(format)
163    }
164}
165
166/// Helper to read a fixed number of big‑endian bytes and return them as `usize`.
167pub struct NbyteReader<const NBYTE: usize>;
168
169macro_rules! impl_read {
170    ($ty:ty) => {
171        /// Read the next big‑endian integer of type `$ty` and return it as
172        /// `usize` from `reader`.
173        pub fn read<'de, R>(reader: &mut R) -> core::result::Result<usize, Error<R::Error>>
174        where
175            R: IoRead<'de>,
176        {
177            const SIZE: usize = core::mem::size_of::<$ty>();
178            let bytes = reader.read_slice(SIZE).map_err(Error::Io)?;
179            let slice = bytes.as_bytes();
180            let data: [u8; SIZE] = slice.try_into().map_err(|_| Error::UnexpectedEof)?;
181            let val =
182                usize::try_from(<$ty>::from_be_bytes(data)).map_err(|_| Error::InvalidData)?;
183            Ok(val)
184        }
185    };
186}
187
188impl NbyteReader<1> {
189    impl_read! {u8}
190}
191
192impl NbyteReader<2> {
193    impl_read! {u16}
194}
195impl NbyteReader<4> {
196    impl_read! {u32}
197}