messagepack_core/encode/
bin.rs

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