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(feature = "alloc")]
145impl<'de, V> DecodeBorrowed<'de> for alloc::vec::Vec<V>
146where
147 V: DecodeBorrowed<'de>,
148{
149 type Value = alloc::vec::Vec<V::Value>;
150
151 fn decode_borrowed_with_format<R>(
152 format: Format,
153 reader: &mut R,
154 ) -> core::result::Result<Self::Value, Error<R::Error>>
155 where
156 R: IoRead<'de>,
157 {
158 let len = match format {
159 Format::FixArray(len) => len.into(),
160 Format::Array16 => NbyteReader::<2>::read(reader)?,
161 Format::Array32 => NbyteReader::<4>::read(reader)?,
162 _ => return Err(Error::UnexpectedFormat),
163 };
164
165 let mut out: alloc::vec::Vec<<V as DecodeBorrowed<'de>>::Value> =
166 alloc::vec::Vec::with_capacity(len);
167 for _ in 0..len {
168 out.push(V::decode_borrowed(reader)?);
169 }
170 Ok(out)
171 }
172}
173
174#[cfg(test)]
175mod tests {
176 use super::*;
177 use crate::decode::Decode;
178 use rstest::rstest;
179
180 #[rstest]
181 #[case(&[0x92, 0x01, 0x02, 0x01], vec![1u8, 2], &[0x01])]
182 #[case(&[0xdc, 0x00, 0x02, 0x2a, 0x2b], vec![42u8, 43], &[])]
183 fn array_decode_success(
184 #[case] buf: &[u8],
185 #[case] expect: Vec<u8>,
186 #[case] rest_expect: &[u8],
187 ) {
188 let mut r = crate::io::SliceReader::new(buf);
189 let decoded = ArrayDecoder::<Vec<u8>, u8>::decode(&mut r).unwrap();
190 assert_eq!(decoded, expect);
191 assert_eq!(r.rest(), rest_expect);
192 }
193
194 #[rstest]
195 fn array_decoder_unexpected_format() {
196 let buf = &[0x81, 0x01, 0x02]; let mut r = crate::io::SliceReader::new(buf);
198 let err = ArrayDecoder::<Vec<u8>, u8>::decode(&mut r).unwrap_err();
199 assert!(matches!(err, Error::UnexpectedFormat));
200 }
201
202 #[rstest]
203 fn fixed_array_len0_success() {
204 let buf = &[0x90]; let mut r = crate::io::SliceReader::new(buf);
206 let arr = <[u8; 0] as Decode>::decode(&mut r).unwrap();
207 assert_eq!(arr, []);
208 assert!(r.rest().is_empty());
209 }
210
211 #[rstest]
212 fn fixed_array_len3_success() {
213 let buf = &[0x93, 0x0a, 0x0b, 0x0c];
214 let mut r = crate::io::SliceReader::new(buf);
215 let arr = <[u8; 3] as Decode>::decode(&mut r).unwrap();
216 assert_eq!(arr, [10u8, 11, 12]);
217 assert!(r.rest().is_empty());
218 }
219
220 #[rstest]
221 #[case(&[0x92, 0x01, 0x02])] #[case(&[0x94, 0x01, 0x02, 0x03, 0x04])] fn fixed_array_len_mismatch(#[case] buf: &[u8]) {
224 let mut r = crate::io::SliceReader::new(buf);
225 let err = <[u8; 3] as Decode>::decode(&mut r).unwrap_err();
226 assert!(matches!(err, Error::InvalidData));
227 }
228
229 #[rstest]
230 fn tuple1_success() {
231 let buf = &[0x91, 0x2a]; let mut r = crate::io::SliceReader::new(buf);
233 let (v0,) = <(u8,) as Decode>::decode(&mut r).unwrap();
234 assert_eq!(v0, 42);
235 assert!(r.rest().is_empty());
236 }
237
238 #[rstest]
239 #[case(&[0x92, 0x2a, 0x2b])] #[case(&[0xdc, 0x00, 0x02, 0x2a, 0x2b])] fn tuple2_success(#[case] buf: &[u8]) {
242 let mut r = crate::io::SliceReader::new(buf);
243 let (a, b) = <(u8, u8) as Decode>::decode(&mut r).unwrap();
244 assert_eq!((a, b), (42, 43));
245 assert!(r.rest().is_empty());
246 }
247
248 #[rstest]
249 fn tuple3_success() {
250 let buf = &[0x93, 0x01, 0x02, 0x03];
251 let mut r = crate::io::SliceReader::new(buf);
252 let (a, b, c) = <(u8, u8, u8) as Decode>::decode(&mut r).unwrap();
253 assert_eq!((a, b, c), (1, 2, 3));
254 assert!(r.rest().is_empty());
255 }
256
257 #[rstest]
258 #[case(&[0x92, 0x01, 0x02])] #[case(&[0xdc, 0x00, 0x04, 1, 2, 3, 4])] fn tuple_len_mismatch(#[case] buf: &[u8]) {
261 let mut r = crate::io::SliceReader::new(buf);
262 let err = <(u8, u8, u8) as Decode>::decode(&mut r).unwrap_err();
263 assert!(matches!(err, Error::InvalidData));
264 }
265
266 #[rstest]
267 fn tuple_unexpected_format() {
268 let buf = &[0x81, 0x01, 0x02]; let mut r = crate::io::SliceReader::new(buf);
270 let err = <(u8,) as Decode>::decode(&mut r).unwrap_err();
271 assert!(matches!(err, Error::UnexpectedFormat));
272 }
273
274 #[cfg(feature = "alloc")]
275 #[test]
276 fn vec_of_u8_success() {
277 let buf = &[0x92, 0x2a, 0x2b]; let mut r = crate::io::SliceReader::new(buf);
279 let v = <alloc::vec::Vec<u8> as Decode>::decode(&mut r).unwrap();
280 assert_eq!(v, alloc::vec![42u8, 43]);
281 assert!(r.rest().is_empty());
282 }
283}