messagepack_core/decode/
array.rs

1//! Array decoding helpers.
2
3use core::marker::PhantomData;
4
5use super::{Decode, Error, NbyteReader, Result};
6use crate::formats::Format;
7
8/// Decode a MessagePack array of `V` into `Array` collecting iterator.
9pub struct ArrayDecoder<Array, V>(PhantomData<(Array, V)>);
10
11impl<'a, Array, V> Decode<'a> for ArrayDecoder<Array, V>
12where
13    V: Decode<'a>,
14    Array: FromIterator<V::Value>,
15{
16    type Value = Array;
17
18    fn decode(buf: &'a [u8]) -> Result<(Self::Value, &'a [u8])> {
19        let (format, buf) = Format::decode(buf)?;
20        match format {
21            Format::FixArray(_) | Format::Array16 | Format::Array32 => {
22                Self::decode_with_format(format, buf)
23            }
24            _ => Err(Error::UnexpectedFormat),
25        }
26    }
27
28    fn decode_with_format(format: Format, buf: &'a [u8]) -> Result<(Self::Value, &'a [u8])> {
29        let (len, buf) = match format {
30            Format::FixArray(len) => (len.into(), buf),
31            Format::Array16 => NbyteReader::<2>::read(buf)?,
32            Format::Array32 => NbyteReader::<4>::read(buf)?,
33            _ => return Err(Error::UnexpectedFormat),
34        };
35
36        let mut buf_ptr = buf;
37        let out = (0..len)
38            .map(|_| {
39                let (v, next) = V::decode(buf_ptr)?;
40                buf_ptr = next;
41                Ok::<_, Error>(v)
42            })
43            .collect::<Result<Array>>()?;
44        Ok((out, buf_ptr))
45    }
46}
47
48impl<'a, const N: usize, V> Decode<'a> for [V; N]
49where
50    V: Decode<'a>,
51{
52    type Value = [V::Value; N];
53    fn decode(buf: &'a [u8]) -> Result<(Self::Value, &'a [u8])> {
54        let (format, buf) = Format::decode(buf)?;
55        match format {
56            Format::FixArray(_) | Format::Array16 | Format::Array32 => {
57                Self::decode_with_format(format, buf)
58            }
59            _ => Err(Error::UnexpectedFormat),
60        }
61    }
62    fn decode_with_format(format: Format, buf: &'a [u8]) -> Result<(Self::Value, &'a [u8])> {
63        let (len, buf) = match format {
64            Format::FixArray(len) => (len.into(), buf),
65            Format::Array16 => NbyteReader::<2>::read(buf)?,
66            Format::Array32 => NbyteReader::<4>::read(buf)?,
67            _ => return Err(Error::UnexpectedFormat),
68        };
69        if len != N {
70            return Err(Error::InvalidData);
71        };
72
73        let mut tmp: [Option<V::Value>; N] = core::array::from_fn(|_| None);
74        let mut buf_ptr = buf;
75        for item in tmp.iter_mut() {
76            let (val, next) = V::decode(buf_ptr)?;
77            *item = Some(val);
78            buf_ptr = next
79        }
80        let out = core::array::from_fn(|i| tmp[i].take().expect("initialized"));
81        Ok((out, buf_ptr))
82    }
83}
84
85macro_rules! tuple_decode_impls {
86    ($($len:expr => ($($n:tt $name:ident)+))+ $(,)?) => {
87        $(
88            impl<'a, $($name),+> Decode<'a> for ($($name,)+)
89            where
90                $($name: Decode<'a>,)+
91            {
92                type Value = ($(<$name as Decode<'a>>::Value,)+);
93
94                fn decode(buf: &'a [u8]) -> Result<(Self::Value, &'a [u8])> {
95                    let (format, buf) = Format::decode(buf)?;
96                    match format {
97                        Format::FixArray(_) | Format::Array16 | Format::Array32 =>
98                            Self::decode_with_format(format, buf),
99                        _ => Err(Error::UnexpectedFormat),
100                    }
101                }
102
103                fn decode_with_format(format: Format, buf: &'a [u8])
104                    -> Result<(Self::Value, &'a [u8])>
105                {
106                    let (len, mut p) = match format {
107                        Format::FixArray(len) => (len.into(), buf),
108                        Format::Array16 => NbyteReader::<2>::read(buf)?,
109                        Format::Array32 => NbyteReader::<4>::read(buf)?,
110                        _ => return Err(Error::UnexpectedFormat),
111                    };
112                    if len != $len {
113                        return Err(Error::InvalidData);
114                    }
115
116                    let value = (
117                        $({
118                            let (v, next) = <$name as Decode<'a>>::decode(p)?;
119                            p = next;
120                            v
121                        },)+
122                    );
123                    Ok((value, p))
124                }
125            }
126        )+
127    };
128}
129
130tuple_decode_impls! {
131    1  => (0 V0)
132    2  => (0 V0 1 V1)
133    3  => (0 V0 1 V1 2 V2)
134    4  => (0 V0 1 V1 2 V2 3 V3)
135    5  => (0 V0 1 V1 2 V2 3 V3 4 V4)
136    6  => (0 V0 1 V1 2 V2 3 V3 4 V4 5 V5)
137    7  => (0 V0 1 V1 2 V2 3 V3 4 V4 5 V5 6 V6)
138    8  => (0 V0 1 V1 2 V2 3 V3 4 V4 5 V5 6 V6 7 V7)
139    9  => (0 V0 1 V1 2 V2 3 V3 4 V4 5 V5 6 V6 7 V7 8 V8)
140    10 => (0 V0 1 V1 2 V2 3 V3 4 V4 5 V5 6 V6 7 V7 8 V8 9 V9)
141    11 => (0 V0 1 V1 2 V2 3 V3 4 V4 5 V5 6 V6 7 V7 8 V8 9 V9 10 V10)
142    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)
143    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)
144    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)
145    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)
146    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)
147}
148
149#[cfg(test)]
150mod tests {
151    use super::*;
152    use rstest::rstest;
153
154    #[rstest]
155    #[case(&[0x92, 0x01, 0x02, 0x01], vec![1u8, 2], &[0x01])]
156    #[case(&[0xdc, 0x00, 0x02, 0x2a, 0x2b], vec![42u8, 43], &[])]
157    fn array_decode_success(
158        #[case] buf: &[u8],
159        #[case] expect: Vec<u8>,
160        #[case] rest_expect: &[u8],
161    ) {
162        let (decoded, rest) = ArrayDecoder::<Vec<u8>, u8>::decode(buf).unwrap();
163        assert_eq!(decoded, expect);
164        assert_eq!(rest, rest_expect);
165    }
166
167    #[rstest]
168    fn array_decoder_unexpected_format() {
169        let buf = &[0x81, 0x01, 0x02]; // map(1)
170        let err = ArrayDecoder::<Vec<u8>, u8>::decode(buf).unwrap_err();
171        assert!(matches!(err, Error::UnexpectedFormat));
172    }
173
174    #[rstest]
175    fn fixed_array_len0_success() {
176        let buf = &[0x90]; // array(0)
177        let (arr, rest) = <[u8; 0] as Decode>::decode(buf).unwrap();
178        assert_eq!(arr, []);
179        assert!(rest.is_empty());
180    }
181
182    #[rstest]
183    fn fixed_array_len3_success() {
184        let buf = &[0x93, 0x0a, 0x0b, 0x0c];
185        let (arr, rest) = <[u8; 3] as Decode>::decode(buf).unwrap();
186        assert_eq!(arr, [10u8, 11, 12]);
187        assert!(rest.is_empty());
188    }
189
190    #[rstest]
191    #[case(&[0x92, 0x01, 0x02])] // len=2
192    #[case(&[0x94, 0x01, 0x02, 0x03, 0x04])] // len=4 
193    fn fixed_array_len_mismatch(#[case] buf: &[u8]) {
194        let err = <[u8; 3] as Decode>::decode(buf).unwrap_err();
195        assert!(matches!(err, Error::InvalidData));
196    }
197
198    #[rstest]
199    fn tuple1_success() {
200        let buf = &[0x91, 0x2a]; // [42]
201        let ((v0,), rest) = <(u8,) as Decode>::decode(buf).unwrap();
202        assert_eq!(v0, 42);
203        assert!(rest.is_empty());
204    }
205
206    #[rstest]
207    #[case(&[0x92, 0x2a, 0x2b])] // fixarray
208    #[case(&[0xdc, 0x00, 0x02, 0x2a, 0x2b])] // array16(2)
209    fn tuple2_success(#[case] buf: &[u8]) {
210        let ((a, b), rest) = <(u8, u8) as Decode>::decode(buf).unwrap();
211        assert_eq!((a, b), (42, 43));
212        assert!(rest.is_empty());
213    }
214
215    #[rstest]
216    fn tuple3_success() {
217        let buf = &[0x93, 0x01, 0x02, 0x03];
218        let ((a, b, c), rest) = <(u8, u8, u8) as Decode>::decode(buf).unwrap();
219        assert_eq!((a, b, c), (1, 2, 3));
220        assert!(rest.is_empty());
221    }
222
223    #[rstest]
224    #[case(&[0x92, 0x01, 0x02])] // len 2
225    #[case(&[0xdc, 0x00, 0x04, 1, 2, 3, 4])] // len 4
226    fn tuple_len_mismatch(#[case] buf: &[u8]) {
227        let err = <(u8, u8, u8) as Decode>::decode(buf).unwrap_err();
228        assert!(matches!(err, Error::InvalidData));
229    }
230
231    #[rstest]
232    fn tuple_unexpected_format() {
233        let buf = &[0x81, 0x01, 0x02]; // map(1)
234        let err = <(u8,) as Decode>::decode(buf).unwrap_err();
235        assert!(matches!(err, Error::UnexpectedFormat));
236    }
237}