Skip to main content

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