messagepack_core/encode/
bin.rs

1//! Binary encoders.
2
3use super::{Encode, Error, Result};
4use crate::{formats::Format, io::IoWrite};
5
6/// Encoder for MessagePack binary values (`bin8/16/32`).
7#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
8pub struct BinaryEncoder<'blob>(pub &'blob [u8]);
9
10impl<'blob> core::ops::Deref for BinaryEncoder<'blob> {
11    type Target = &'blob [u8];
12    fn deref(&self) -> &Self::Target {
13        &self.0
14    }
15}
16
17impl<W: IoWrite> Encode<W> for BinaryEncoder<'_> {
18    fn encode(&self, writer: &mut W) -> Result<usize, <W as IoWrite>::Error> {
19        let self_len = self.len();
20        let format_len = match self_len {
21            0x00..=0xff => {
22                let cast = self_len as u8;
23                writer.write(&[Format::Bin8.as_byte(), cast])?;
24                Ok(2)
25            }
26            0x100..=0xffff => {
27                let cast = (self_len as u16).to_be_bytes();
28                writer.write(&[Format::Bin16.as_byte(), cast[0], cast[1]])?;
29                Ok(3)
30            }
31            0x10000..=0xffffffff => {
32                let cast = (self_len as u32).to_be_bytes();
33                writer.write(&[Format::Bin32.as_byte(), cast[0], cast[1], cast[2], cast[3]])?;
34
35                Ok(5)
36            }
37            _ => Err(Error::InvalidFormat),
38        }?;
39
40        writer.write(self.0)?;
41        Ok(format_len + self_len)
42    }
43}
44
45#[cfg(test)]
46mod tests {
47    use super::*;
48    use rstest::rstest;
49
50    #[rstest]
51    #[case(0xc4, 255_u8.to_be_bytes(),[0x12;255])]
52    #[case(0xc5, 65535_u16.to_be_bytes(),[0x34;65535])]
53    #[case(0xc6, 65536_u32.to_be_bytes(),[0x56;65536])]
54    fn encode_str_sized<S: AsRef<[u8]>, D: AsRef<[u8]>>(
55        #[case] marker: u8,
56        #[case] size: S,
57        #[case] data: D,
58    ) {
59        let expected = marker
60            .to_be_bytes()
61            .iter()
62            .chain(size.as_ref())
63            .chain(data.as_ref())
64            .cloned()
65            .collect::<Vec<u8>>();
66
67        let encoder = BinaryEncoder(data.as_ref());
68
69        let mut buf = vec![];
70        let n = encoder.encode(&mut buf).unwrap();
71
72        assert_eq!(&buf, &expected);
73        assert_eq!(n, expected.len());
74    }
75}