messagepack_core/encode/
array.rs1use super::{Encode, Error, Result};
4use crate::{formats::Format, io::IoWrite};
5
6pub struct ArrayFormatEncoder(pub usize);
8
9impl Encode for ArrayFormatEncoder {
10 fn encode<W: IoWrite>(&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<V: Encode> Encode for &[V] {
41 fn encode<W: IoWrite>(&self, writer: &mut W) -> Result<usize, <W as IoWrite>::Error> {
42 let format_len = ArrayFormatEncoder(self.len()).encode(writer)?;
43 let array_len = self
44 .iter()
45 .map(|v| v.encode(writer))
46 .try_fold(0, |acc, v| v.map(|n| acc + n))?;
47 Ok(format_len + array_len)
48 }
49}
50
51impl<const N: usize, V: Encode> Encode for [V; N] {
52 fn encode<W: IoWrite>(&self, writer: &mut W) -> Result<usize, <W as IoWrite>::Error> {
53 self.as_slice().encode(writer)
54 }
55}
56
57macro_rules! tuple_impls {
58 ($($len:expr => ($($n:tt $name:ident)+))+ $(,)?) => {
59 $(
60 tuple_impls!(@impl $len; $($n $name)+);
61 )+
62 };
63 (@impl $len:expr; $($n:tt $name:ident)+) => {
64 impl<$($name: Encode),+> Encode for ($($name,)+) {
65 fn encode<W: IoWrite>(&self, writer: &mut W) -> Result<usize, <W as IoWrite>::Error> {
66 let format_len = ArrayFormatEncoder($len).encode(writer)?;
67 let mut array_len = 0;
68 $(
69 array_len += self.$n.encode(writer)?;
70 )+
71 Ok(format_len + array_len)
72 }
73 }
74 };
75}
76
77tuple_impls! {
78 1 => (0 V0)
79 2 => (0 V0 1 V1)
80 3 => (0 V0 1 V1 2 V2)
81 4 => (0 V0 1 V1 2 V2 3 V3)
82 5 => (0 V0 1 V1 2 V2 3 V3 4 V4)
83 6 => (0 V0 1 V1 2 V2 3 V3 4 V4 5 V5)
84 7 => (0 V0 1 V1 2 V2 3 V3 4 V4 5 V5 6 V6)
85 8 => (0 V0 1 V1 2 V2 3 V3 4 V4 5 V5 6 V6 7 V7)
86 9 => (0 V0 1 V1 2 V2 3 V3 4 V4 5 V5 6 V6 7 V7 8 V8)
87 10 => (0 V0 1 V1 2 V2 3 V3 4 V4 5 V5 6 V6 7 V7 8 V8 9 V9)
88 11 => (0 V0 1 V1 2 V2 3 V3 4 V4 5 V5 6 V6 7 V7 8 V8 9 V9 10 V10)
89 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)
90 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)
91 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)
92 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)
93 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)
94}
95
96#[cfg(feature = "alloc")]
97impl<V: Encode> Encode for alloc::vec::Vec<V> {
98 fn encode<W: IoWrite>(&self, writer: &mut W) -> Result<usize, <W as IoWrite>::Error> {
99 self.as_slice().encode(writer)
100 }
101}
102
103#[cfg(test)]
104mod tests {
105 use super::*;
106 use rstest::rstest;
107
108 #[rstest]
109 #[case([1u8, 2u8, 3u8],[0x93, 0x01, 0x02, 0x03])]
110 fn encode_fix_array<V: Encode, Array: AsRef<[V]>, E: AsRef<[u8]> + Sized>(
111 #[case] value: Array,
112 #[case] expected: E,
113 ) {
114 let expected = expected.as_ref();
115
116 let mut buf = vec![];
117 let n = value.as_ref().encode(&mut buf).unwrap();
118 assert_eq!(buf, expected);
119 assert_eq!(n, expected.len());
120 }
121
122 #[rstest]
123 #[case(0xdc, 65535_u16.to_be_bytes(),[0x34;65535])]
124 #[case(0xdd, 65536_u32.to_be_bytes(),[0x56;65536])]
125 fn encode_array_sized<S: AsRef<[u8]>, D: AsRef<[u8]>>(
126 #[case] marker: u8,
127 #[case] size: S,
128 #[case] data: D,
129 ) {
130 let expected = marker
131 .to_be_bytes()
132 .iter()
133 .chain(size.as_ref())
134 .chain(data.as_ref())
135 .cloned()
136 .collect::<Vec<u8>>();
137
138 let mut buf = vec![];
139 let n = data.as_ref().encode(&mut buf).unwrap();
140
141 assert_eq!(&buf, &expected);
142 assert_eq!(n, expected.len());
143 }
144
145 #[rstest]
146 #[case((1u8,), &[0x91,0x01])]
147 #[case((1u8,2u8), &[0x92,0x01,0x02])]
148 #[case((1u8,2u8,3u8), &[0x93,0x01,0x02,0x03])]
149 fn encode_tuple<V: Encode>(#[case] v: V, #[case] expected: &[u8]) {
150 let mut buf = Vec::new();
151 let _ = v.encode(&mut buf).unwrap();
152 assert_eq!(buf, expected);
153 }
154
155 #[cfg(feature = "alloc")]
156 #[test]
157 fn encode_vec_via_slice() {
158 let v = alloc::vec![1u8, 2, 3];
159 let mut buf = alloc::vec::Vec::new();
160 let _ = v.encode(&mut buf).unwrap();
161 assert_eq!(buf, alloc::vec![0x93, 0x01, 0x02, 0x03]);
162 }
163}