messagepack_core/extension/
encode.rs

1use super::{ExtensionRef, FixedExtension};
2use super::{U16_MAX, U32_MAX};
3use crate::encode::{self, Encode};
4use crate::formats::Format;
5use crate::io::IoWrite;
6
7impl<'a, W: IoWrite> Encode<W> for ExtensionRef<'a> {
8    fn encode(&self, writer: &mut W) -> core::result::Result<usize, encode::Error<W::Error>> {
9        let data_len = self.data.len();
10        let type_byte = self.r#type.to_be_bytes()[0];
11
12        match data_len {
13            1 => {
14                writer.write(&[Format::FixExt1.as_byte(), type_byte])?;
15                writer.write(self.data)?;
16                Ok(2 + data_len)
17            }
18            2 => {
19                writer.write(&[Format::FixExt2.as_byte(), type_byte])?;
20                writer.write(self.data)?;
21                Ok(2 + data_len)
22            }
23            4 => {
24                writer.write(&[Format::FixExt4.as_byte(), type_byte])?;
25                writer.write(self.data)?;
26                Ok(2 + data_len)
27            }
28            8 => {
29                writer.write(&[Format::FixExt8.as_byte(), type_byte])?;
30                writer.write(self.data)?;
31                Ok(2 + data_len)
32            }
33            16 => {
34                writer.write(&[Format::FixExt16.as_byte(), type_byte])?;
35                writer.write(self.data)?;
36                Ok(2 + data_len)
37            }
38            0..=0xff => {
39                let cast = data_len as u8;
40                writer.write(&[Format::Ext8.as_byte(), cast, type_byte])?;
41                writer.write(self.data)?;
42                Ok(3 + data_len)
43            }
44            0x100..=U16_MAX => {
45                let cast = (data_len as u16).to_be_bytes();
46                writer.write(&[Format::Ext16.as_byte(), cast[0], cast[1], type_byte])?;
47                writer.write(self.data)?;
48                Ok(4 + data_len)
49            }
50            0x1_0000..=U32_MAX => {
51                let cast = (data_len as u32).to_be_bytes();
52                writer.write(&[
53                    Format::Ext32.as_byte(),
54                    cast[0],
55                    cast[1],
56                    cast[2],
57                    cast[3],
58                    type_byte,
59                ])?;
60                writer.write(self.data)?;
61                Ok(6 + data_len)
62            }
63            _ => Err(encode::Error::InvalidFormat),
64        }
65    }
66}
67
68impl<const N: usize, W: IoWrite> Encode<W> for FixedExtension<N> {
69    fn encode(&self, writer: &mut W) -> core::result::Result<usize, encode::Error<W::Error>> {
70        self.as_ref().encode(writer)
71    }
72}
73
74#[cfg(feature = "alloc")]
75impl<W: IoWrite> Encode<W> for super::owned::ExtensionOwned {
76    fn encode(&self, writer: &mut W) -> core::result::Result<usize, encode::Error<W::Error>> {
77        self.as_ref().encode(writer)
78    }
79}
80
81#[cfg(test)]
82mod tests {
83    use super::*;
84
85    #[rstest::rstest]
86    #[case(0xd4,123,[0x12])]
87    #[case(0xd5,123,[0x12,0x34])]
88    #[case(0xd6,123,[0x12,0x34,0x56,0x78])]
89    #[case(0xd7,123,[0x12;8])]
90    #[case(0xd8,123,[0x12;16])]
91    fn encode_ext_fixed<D: AsRef<[u8]>>(#[case] marker: u8, #[case] ty: i8, #[case] data: D) {
92        let expected = marker
93            .to_be_bytes()
94            .iter()
95            .chain(ty.to_be_bytes().iter())
96            .chain(data.as_ref())
97            .cloned()
98            .collect::<Vec<_>>();
99
100        let encoder = ExtensionRef::new(ty, data.as_ref());
101
102        let mut buf = vec![];
103        let n = encoder.encode(&mut buf).unwrap();
104
105        assert_eq!(&buf, &expected);
106        assert_eq!(n, expected.len());
107    }
108
109    #[rstest::rstest]
110    #[case(0xc7_u8.to_be_bytes(),123,5u8.to_be_bytes(),[0x12;5])]
111    #[case(0xc8_u8.to_be_bytes(),123,65535_u16.to_be_bytes(),[0x34;65535])]
112    #[case(0xc9_u8.to_be_bytes(),123,65536_u32.to_be_bytes(),[0x56;65536])]
113    fn encode_ext_sized<M: AsRef<[u8]>, S: AsRef<[u8]>, D: AsRef<[u8]>>(
114        #[case] marker: M,
115        #[case] ty: i8,
116        #[case] size: S,
117        #[case] data: D,
118    ) {
119        let expected = marker
120            .as_ref()
121            .iter()
122            .chain(size.as_ref())
123            .chain(ty.to_be_bytes().iter())
124            .chain(data.as_ref())
125            .cloned()
126            .collect::<Vec<_>>();
127
128        let encoder = ExtensionRef::new(ty, data.as_ref());
129
130        let mut buf = vec![];
131        let n = encoder.encode(&mut buf).unwrap();
132
133        assert_eq!(&buf, &expected);
134        assert_eq!(n, expected.len());
135    }
136}