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