messagepack_core/encode/
array.rs1use super::{Encode, Error, Result};
4use crate::{formats::Format, io::IoWrite};
5
6pub struct ArrayFormatEncoder(pub usize);
8
9impl<W: IoWrite> Encode<W> for ArrayFormatEncoder {
10 fn encode(&self, writer: &mut W) -> Result<usize, <W as IoWrite>::Error> {
11 match self.0 {
12 0x00..=0b1111 => {
13 let cast = self.0 as u8;
14 writer.write(&[Format::FixArray(cast).as_byte()])?;
15 Ok(1)
16 }
17 0x10..=0xffff => {
18 let cast = (self.0 as u16).to_be_bytes();
19 writer.write(&[Format::Array16.as_byte(), cast[0], cast[1]])?;
20
21 Ok(3)
22 }
23 0x10000..=0xffffffff => {
24 let cast = (self.0 as u32).to_be_bytes();
25 writer.write(&[
26 Format::Array32.as_byte(),
27 cast[0],
28 cast[1],
29 cast[2],
30 cast[3],
31 ])?;
32
33 Ok(5)
34 }
35 _ => Err(Error::InvalidFormat),
36 }
37 }
38}
39
40impl<W, V> Encode<W> for &[V]
41where
42 W: IoWrite,
43 V: Encode<W>,
44{
45 fn encode(&self, writer: &mut W) -> Result<usize, <W as IoWrite>::Error> {
46 let format_len = ArrayFormatEncoder(self.len()).encode(writer)?;
47 let array_len = self
48 .iter()
49 .map(|v| v.encode(writer))
50 .try_fold(0, |acc, v| v.map(|n| acc + n))?;
51 Ok(format_len + array_len)
52 }
53}
54
55impl<const N: usize, W, V> Encode<W> for [V; N]
56where
57 W: IoWrite,
58 V: Encode<W>,
59{
60 fn encode(&self, writer: &mut W) -> Result<usize, <W as IoWrite>::Error> {
61 self.as_slice().encode(writer)
62 }
63}
64
65macro_rules! tuple_impls {
66 ($($len:expr => ($($n:tt $name:ident)+))+ $(,)?) => {
67 $(
68 tuple_impls!(@impl $len; $($n $name)+);
69 )+
70 };
71 (@impl $len:expr; $($n:tt $name:ident)+) => {
72 impl<W, $($name),+> Encode<W> for ($($name,)+)
73 where
74 W: IoWrite,
75 $($name: Encode<W>,)+
76 {
77 fn encode(&self, writer: &mut W) -> Result<usize, <W as IoWrite>::Error> {
78 let format_len = ArrayFormatEncoder($len).encode(writer)?;
79 let mut array_len = 0;
80 $(
81 array_len += self.$n.encode(writer)?;
82 )+
83 Ok(format_len + array_len)
84 }
85 }
86 };
87}
88
89tuple_impls! {
90 1 => (0 V0)
91 2 => (0 V0 1 V1)
92 3 => (0 V0 1 V1 2 V2)
93 4 => (0 V0 1 V1 2 V2 3 V3)
94 5 => (0 V0 1 V1 2 V2 3 V3 4 V4)
95 6 => (0 V0 1 V1 2 V2 3 V3 4 V4 5 V5)
96 7 => (0 V0 1 V1 2 V2 3 V3 4 V4 5 V5 6 V6)
97 8 => (0 V0 1 V1 2 V2 3 V3 4 V4 5 V5 6 V6 7 V7)
98 9 => (0 V0 1 V1 2 V2 3 V3 4 V4 5 V5 6 V6 7 V7 8 V8)
99 10 => (0 V0 1 V1 2 V2 3 V3 4 V4 5 V5 6 V6 7 V7 8 V8 9 V9)
100 11 => (0 V0 1 V1 2 V2 3 V3 4 V4 5 V5 6 V6 7 V7 8 V8 9 V9 10 V10)
101 12 => (0 V0 1 V1 2 V2 3 V3 4 V4 5 V5 6 V6 7 V7 8 V8 9 V9 10 V10 11 V11)
102 13 => (0 V0 1 V1 2 V2 3 V3 4 V4 5 V5 6 V6 7 V7 8 V8 9 V9 10 V10 11 V11 12 V12)
103 14 => (0 V0 1 V1 2 V2 3 V3 4 V4 5 V5 6 V6 7 V7 8 V8 9 V9 10 V10 11 V11 12 V12 13 V13)
104 15 => (0 V0 1 V1 2 V2 3 V3 4 V4 5 V5 6 V6 7 V7 8 V8 9 V9 10 V10 11 V11 12 V12 13 V13 14 V14)
105 16 => (0 V0 1 V1 2 V2 3 V3 4 V4 5 V5 6 V6 7 V7 8 V8 9 V9 10 V10 11 V11 12 V12 13 V13 14 V14 15 V15)
106}
107
108#[cfg(feature = "alloc")]
109impl<W, V> Encode<W> for alloc::vec::Vec<V>
110where
111 W: IoWrite,
112 V: Encode<W>,
113{
114 fn encode(&self, writer: &mut W) -> Result<usize, <W as IoWrite>::Error> {
115 self.as_slice().encode(writer)
116 }
117}
118
119#[cfg(test)]
120mod tests {
121 use super::*;
122 use rstest::rstest;
123
124 #[rstest]
125 #[case([1u8, 2u8, 3u8],[0x93, 0x01, 0x02, 0x03])]
126 fn encode_fix_array<V: Encode<Vec<u8>>, Array: AsRef<[V]>, E: AsRef<[u8]> + Sized>(
127 #[case] value: Array,
128 #[case] expected: E,
129 ) {
130 let expected = expected.as_ref();
131
132 let mut buf = vec![];
133 let n = value.as_ref().encode(&mut buf).unwrap();
134 assert_eq!(buf, expected);
135 assert_eq!(n, expected.len());
136 }
137
138 #[rstest]
139 #[case(0xdc, 65535_u16.to_be_bytes(),[0x34;65535])]
140 #[case(0xdd, 65536_u32.to_be_bytes(),[0x56;65536])]
141 fn encode_array_sized<S: AsRef<[u8]>, D: AsRef<[u8]>>(
142 #[case] marker: u8,
143 #[case] size: S,
144 #[case] data: D,
145 ) {
146 let expected = marker
147 .to_be_bytes()
148 .iter()
149 .chain(size.as_ref())
150 .chain(data.as_ref())
151 .cloned()
152 .collect::<Vec<u8>>();
153
154 let mut buf = vec![];
155 let n = data.as_ref().encode(&mut buf).unwrap();
156
157 assert_eq!(&buf, &expected);
158 assert_eq!(n, expected.len());
159 }
160
161 #[rstest]
162 #[case((1u8,), &[0x91,0x01])]
163 #[case((1u8,2u8), &[0x92,0x01,0x02])]
164 #[case((1u8,2u8,3u8), &[0x93,0x01,0x02,0x03])]
165 fn encode_tuple<V: Encode<Vec<u8>>>(#[case] v: V, #[case] expected: &[u8]) {
166 let mut buf = Vec::new();
167 let _ = v.encode(&mut buf).unwrap();
168 assert_eq!(buf, expected);
169 }
170
171 #[cfg(feature = "alloc")]
172 #[test]
173 fn encode_vec_via_slice() {
174 let v = alloc::vec![1u8, 2, 3];
175 let mut buf = alloc::vec::Vec::new();
176 let _ = v.encode(&mut buf).unwrap();
177 assert_eq!(buf, alloc::vec![0x93, 0x01, 0x02, 0x03]);
178 }
179}