messagepack_core/decode/
mod.rs

1//! Decoding primitives for MessagePack.
2//!
3//! This module provides low-level decoders that operate on byte slices and
4//! return decoded values along with the remaining tail.
5
6use crate::Format;
7
8mod array;
9pub use array::ArrayDecoder;
10mod bin;
11pub use bin::BinDecoder;
12mod bool;
13mod float;
14mod int;
15mod map;
16pub use map::MapDecoder;
17mod nil;
18pub use nil::NilDecoder;
19mod str;
20pub use str::StrDecoder;
21mod timestamp;
22
23/// MessagePack decode error
24#[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq)]
25pub enum Error {
26    /// Invalid data
27    InvalidData,
28    /// Unexpected format
29    UnexpectedFormat,
30    /// Eof while decode format
31    EofFormat,
32    /// Eof while decode data
33    EofData,
34}
35
36impl core::fmt::Display for Error {
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::EofFormat => write!(f, "EOF while parse format"),
42            Error::EofData => write!(f, "EOF while parse data"),
43        }
44    }
45}
46
47impl core::error::Error for Error {}
48
49/// Result alias used by the decoders in this module.
50type Result<T> = ::core::result::Result<T, Error>;
51
52/// A type that can be decoded from a MessagePack byte slice.
53pub trait Decode<'a> {
54    /// The materialised value type.
55    type Value: Sized;
56    /// Decode a value from the front of `buf`, returning the value and the
57    /// remaining slice.
58    fn decode(buf: &'a [u8]) -> Result<(Self::Value, &'a [u8])>;
59
60    /// Decode a value assuming the leading MessagePack format has already been
61    /// read by the caller. Implementations must validate that `format` is
62    /// appropriate for the type and return an error otherwise.
63    fn decode_with_format(format: Format, buf: &'a [u8]) -> Result<(Self::Value, &'a [u8])>;
64}
65
66impl<'a> Decode<'a> for Format {
67    type Value = Self;
68    fn decode(buf: &'a [u8]) -> Result<(Self::Value, &'a [u8])> {
69        let (first, rest) = buf.split_first().ok_or(Error::EofFormat)?;
70
71        Ok((Self::from_byte(*first), rest))
72    }
73
74    fn decode_with_format(format: Format, buf: &'a [u8]) -> Result<(Self::Value, &'a [u8])> {
75        let _ = (format, buf);
76        unreachable!()
77    }
78}
79
80/// Helper to read a fixed number of big‑endian bytes and return them as `usize`.
81pub struct NbyteReader<const NBYTE: usize>;
82
83macro_rules! impl_read {
84    ($ty:ty) => {
85        /// Read the next big‑endian integer of type `$ty` and return it as
86        /// `usize` together with the remaining slice.
87        pub fn read(buf: &[u8]) -> Result<(usize, &[u8])> {
88            const SIZE: usize = core::mem::size_of::<$ty>();
89            let (data, rest) = buf.split_at_checked(SIZE).ok_or(Error::EofData)?;
90            let data: [u8; SIZE] = data.try_into().map_err(|_| Error::EofData)?;
91            let val =
92                usize::try_from(<$ty>::from_be_bytes(data)).map_err(|_| Error::InvalidData)?;
93            Ok((val, rest))
94        }
95    };
96}
97
98impl NbyteReader<1> {
99    impl_read! {u8}
100}
101
102impl NbyteReader<2> {
103    impl_read! {u16}
104}
105impl NbyteReader<4> {
106    impl_read! {u32}
107}