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