messagepack_core/decode/
bin.rs

1//! Binary (bin8/16/32) decoding helpers.
2
3use super::{Decode, Error, NbyteReader, Result};
4use crate::formats::Format;
5
6/// Decode a MessagePack binary blob and return a borrowed byte slice.
7pub struct BinDecoder;
8
9impl<'a> Decode<'a> for BinDecoder {
10    type Value = &'a [u8];
11    fn decode(buf: &'a [u8]) -> Result<(Self::Value, &'a [u8])> {
12        let (format, buf) = Format::decode(buf)?;
13        match format {
14            Format::Bin8 | Format::Bin16 | Format::Bin32 => Self::decode_with_format(format, buf),
15            _ => Err(Error::UnexpectedFormat),
16        }
17    }
18    fn decode_with_format(format: Format, buf: &'a [u8]) -> Result<(Self::Value, &'a [u8])> {
19        let (len, buf) = match format {
20            Format::Bin8 => NbyteReader::<1>::read(buf)?,
21            Format::Bin16 => NbyteReader::<2>::read(buf)?,
22            Format::Bin32 => NbyteReader::<4>::read(buf)?,
23            _ => return Err(Error::UnexpectedFormat),
24        };
25        let (data, rest) = buf.split_at_checked(len).ok_or(Error::EofData)?;
26        Ok((data, rest))
27    }
28}
29
30impl<'a> Decode<'a> for &'a [u8] {
31    type Value = &'a [u8];
32    fn decode(buf: &'a [u8]) -> Result<(Self::Value, &'a [u8])> {
33        BinDecoder::decode(buf)
34    }
35    fn decode_with_format(format: Format, buf: &'a [u8]) -> Result<(Self::Value, &'a [u8])> {
36        BinDecoder::decode_with_format(format, buf)
37    }
38}
39
40#[cfg(test)]
41mod tests {
42    use super::*;
43    #[test]
44    fn decode_bin8() {
45        let expect = r#"
46MessagePack
47"#
48        .as_bytes();
49        let len = u8::try_from(expect.len()).unwrap();
50        let buf = [0xc4_u8]
51            .into_iter()
52            .chain(len.to_be_bytes())
53            .chain(expect.iter().cloned())
54            .collect::<Vec<_>>();
55
56        let (decoded, rest) = BinDecoder::decode(&buf).unwrap();
57        assert_eq!(decoded, expect);
58        assert_eq!(rest.len(), 0);
59    }
60
61    #[test]
62    fn decode_bin16() {
63        let expect = r#"
64MessagePack is an object serialization specification like JSON.
65
66MessagePack has two concepts: type system and formats.
67
68Serialization is conversion from application objects into MessagePack formats via MessagePack type system.
69
70Deserialization is conversion from MessagePack formats into application objects via MessagePack type system.
71"#.as_bytes();
72        let len = u16::try_from(expect.len()).unwrap();
73        let buf = [0xc5_u8]
74            .into_iter()
75            .chain(len.to_be_bytes())
76            .chain(expect.iter().cloned())
77            .collect::<Vec<_>>();
78
79        let (decoded, rest) = BinDecoder::decode(&buf).unwrap();
80        assert_eq!(decoded, expect);
81        assert_eq!(rest.len(), 0);
82    }
83
84    #[test]
85    fn decode_bin32() {
86        let expect = include_str!("bin.rs").as_bytes();
87        let len = u32::try_from(expect.len()).unwrap();
88        let buf = [0xc6_u8]
89            .into_iter()
90            .chain(len.to_be_bytes())
91            .chain(expect.iter().cloned())
92            .collect::<Vec<_>>();
93
94        let (decoded, rest) = BinDecoder::decode(&buf).unwrap();
95        assert_eq!(decoded, expect);
96        assert_eq!(rest.len(), 0);
97    }
98}