messagepack_core/decode/
bin.rs

1//! Binary (bin8/16/32) decoding helpers.
2
3use super::{Error, NbyteReader};
4use crate::{Decode, decode::DecodeBorrowed, formats::Format, io::IoRead};
5
6/// Decode a MessagePack binary blob and return a borrowed byte slice.
7pub struct BinDecoder;
8
9impl<'de> DecodeBorrowed<'de> for BinDecoder {
10    type Value = &'de [u8];
11
12    fn decode_borrowed_with_format<R>(
13        format: Format,
14        reader: &mut R,
15    ) -> core::result::Result<Self::Value, Error<R::Error>>
16    where
17        R: IoRead<'de>,
18    {
19        let data = ReferenceDecoder::decode_with_format(format, reader)?;
20        match data {
21            crate::io::Reference::Borrowed(b) => Ok(b),
22            crate::io::Reference::Copied(_) => Err(Error::InvalidData),
23        }
24    }
25}
26
27impl<'de> DecodeBorrowed<'de> for &'de [u8] {
28    type Value = &'de [u8];
29
30    fn decode_borrowed_with_format<R>(
31        format: Format,
32        reader: &mut R,
33    ) -> core::result::Result<Self::Value, Error<R::Error>>
34    where
35        R: IoRead<'de>,
36    {
37        BinDecoder::decode_borrowed_with_format(format, reader)
38    }
39}
40
41/// Decode a MessagePack binary and return a `Reference` to its bytes
42pub struct ReferenceDecoder;
43
44impl<'de> super::Decode<'de> for ReferenceDecoder {
45    type Value<'a>
46        = crate::io::Reference<'de, 'a>
47    where
48        Self: 'a,
49        'de: 'a;
50    fn decode_with_format<'a, R>(
51        format: Format,
52        reader: &'a mut R,
53    ) -> Result<Self::Value<'a>, Error<R::Error>>
54    where
55        R: IoRead<'de>,
56        'de: 'a,
57    {
58        let len = match format {
59            Format::Bin8 => NbyteReader::<1>::read(reader)?,
60            Format::Bin16 => NbyteReader::<2>::read(reader)?,
61            Format::Bin32 => NbyteReader::<4>::read(reader)?,
62            _ => return Err(Error::UnexpectedFormat),
63        };
64        let data = reader.read_slice(len).map_err(Error::Io)?;
65        Ok(data)
66    }
67}
68
69/// Owned `Vec<u8>` decoder for MessagePack bin8/16/32.
70#[cfg(feature = "alloc")]
71pub struct BinOwnedDecoder;
72
73#[cfg(feature = "alloc")]
74impl<'de> super::DecodeBorrowed<'de> for BinOwnedDecoder {
75    type Value = alloc::vec::Vec<u8>;
76
77    fn decode_borrowed_with_format<R>(
78        format: Format,
79        reader: &mut R,
80    ) -> Result<<Self as DecodeBorrowed<'de>>::Value, Error<R::Error>>
81    where
82        R: IoRead<'de>,
83    {
84        let val = ReferenceDecoder::decode_with_format(format, reader)?;
85        Ok(val.as_bytes().to_vec())
86    }
87}
88
89#[cfg(test)]
90mod tests {
91    use super::*;
92    use crate::decode::Decode;
93    #[test]
94    fn decode_bin8() {
95        let expect = r#"
96MessagePack
97"#
98        .as_bytes();
99        let len = u8::try_from(expect.len()).unwrap();
100        let buf = [0xc4_u8]
101            .into_iter()
102            .chain(len.to_be_bytes())
103            .chain(expect.iter().cloned())
104            .collect::<Vec<_>>();
105
106        let mut r = crate::io::SliceReader::new(&buf);
107        let decoded = BinDecoder::decode(&mut r).unwrap();
108        assert_eq!(decoded, expect);
109        assert_eq!(r.rest().len(), 0);
110    }
111
112    #[test]
113    fn decode_bin16() {
114        let expect = r#"
115MessagePack is an object serialization specification like JSON.
116
117MessagePack has two concepts: type system and formats.
118
119Serialization is conversion from application objects into MessagePack formats via MessagePack type system.
120
121Deserialization is conversion from MessagePack formats into application objects via MessagePack type system.
122"#.as_bytes();
123        let len = u16::try_from(expect.len()).unwrap();
124        let buf = [0xc5_u8]
125            .into_iter()
126            .chain(len.to_be_bytes())
127            .chain(expect.iter().cloned())
128            .collect::<Vec<_>>();
129
130        let mut r = crate::io::SliceReader::new(&buf);
131        let decoded = BinDecoder::decode(&mut r).unwrap();
132        assert_eq!(decoded, expect);
133        assert_eq!(r.rest().len(), 0);
134    }
135
136    #[test]
137    fn decode_bin32() {
138        let expect = include_str!("bin.rs").as_bytes();
139        let len = u32::try_from(expect.len()).unwrap();
140        let buf = [0xc6_u8]
141            .into_iter()
142            .chain(len.to_be_bytes())
143            .chain(expect.iter().cloned())
144            .collect::<Vec<_>>();
145
146        let mut r = crate::io::SliceReader::new(&buf);
147        let decoded = BinDecoder::decode(&mut r).unwrap();
148        assert_eq!(decoded, expect);
149        assert_eq!(r.rest().len(), 0);
150    }
151
152    #[cfg(feature = "alloc")]
153    #[test]
154    fn decode_vec_u8_owned() {
155        // bin8 with 3 bytes
156        let buf = [0xc4, 0x03, 0x01, 0x02, 0x03];
157        let mut r = crate::io::SliceReader::new(&buf);
158        let v = <BinOwnedDecoder as Decode>::decode(&mut r).unwrap();
159        assert_eq!(v, alloc::vec![1u8, 2, 3]);
160        assert!(r.rest().is_empty());
161    }
162}