1use alloc::boxed::Box;
2use alloc::string::String;
3use alloc::vec::Vec;
4use arrayvec::ArrayVec;
5use core::num::NonZeroUsize;
6
7use crate::codec_err::DecodeError;
8use crate::nested_de_input::NestedDecodeInput;
9use crate::num_conv::bytes_to_number;
10use crate::TypeInfo;
11
12pub trait NestedDecode: Sized {
14 #[doc(hidden)]
17 const TYPE_INFO: TypeInfo = TypeInfo::Unknown;
18
19 fn dep_decode<I: NestedDecodeInput>(input: &mut I) -> Result<Self, DecodeError>;
23
24 fn dep_decode_or_exit<I: NestedDecodeInput, ExitCtx: Clone>(
28 input: &mut I,
29 c: ExitCtx,
30 exit: fn(ExitCtx, DecodeError) -> !,
31 ) -> Self {
32 match Self::dep_decode(input) {
33 Ok(v) => v,
34 Err(e) => exit(c, e),
35 }
36 }
37}
38
39pub fn dep_decode_from_byte_slice<D: NestedDecode>(input: &[u8]) -> Result<D, DecodeError> {
44 let mut_slice = &mut &*input;
45 let result = D::dep_decode(mut_slice);
46 if !mut_slice.is_empty() {
47 return Err(DecodeError::INPUT_TOO_LONG);
48 }
49 result
50}
51
52pub fn dep_decode_from_byte_slice_or_exit<D: NestedDecode, ExitCtx: Clone>(
53 input: &[u8],
54 c: ExitCtx,
55 exit: fn(ExitCtx, DecodeError) -> !,
56) -> D {
57 let mut_slice = &mut &*input;
58 let result = D::dep_decode_or_exit(mut_slice, c.clone(), exit);
59 if !mut_slice.is_empty() {
60 exit(c, DecodeError::INPUT_TOO_LONG);
61 }
62 result
63}
64
65impl NestedDecode for () {
66 const TYPE_INFO: TypeInfo = TypeInfo::Unit;
67
68 fn dep_decode<I: NestedDecodeInput>(_: &mut I) -> Result<(), DecodeError> {
69 Ok(())
70 }
71
72 fn dep_decode_or_exit<I: NestedDecodeInput, ExitCtx: Clone>(
73 _: &mut I,
74 _: ExitCtx,
75 _: fn(ExitCtx, DecodeError) -> !,
76 ) -> Self {
77 }
78}
79
80impl NestedDecode for u8 {
81 const TYPE_INFO: TypeInfo = TypeInfo::U8;
82
83 fn dep_decode<I: NestedDecodeInput>(input: &mut I) -> Result<Self, DecodeError> {
84 input.read_byte()
85 }
86
87 fn dep_decode_or_exit<I: NestedDecodeInput, ExitCtx: Clone>(
88 input: &mut I,
89 c: ExitCtx,
90 exit: fn(ExitCtx, DecodeError) -> !,
91 ) -> Self {
92 input.read_byte_or_exit(c, exit)
93 }
94}
95
96impl<T: NestedDecode> NestedDecode for Vec<T> {
97 fn dep_decode<I: NestedDecodeInput>(input: &mut I) -> Result<Self, DecodeError> {
98 let size = usize::dep_decode(input)?;
99 match T::TYPE_INFO {
100 TypeInfo::U8 => {
101 let bytes = input.read_slice(size)?;
102 let bytes_copy = bytes.to_vec(); let cast_vec: Vec<T> = unsafe { core::mem::transmute(bytes_copy) };
104 Ok(cast_vec)
105 },
106 _ => {
107 let mut result: Vec<T> = Vec::with_capacity(size);
108 for _ in 0..size {
109 result.push(T::dep_decode(input)?);
110 }
111 Ok(result)
112 },
113 }
114 }
115
116 fn dep_decode_or_exit<I: NestedDecodeInput, ExitCtx: Clone>(
117 input: &mut I,
118 c: ExitCtx,
119 exit: fn(ExitCtx, DecodeError) -> !,
120 ) -> Self {
121 let size = usize::dep_decode_or_exit(input, c.clone(), exit);
122 match T::TYPE_INFO {
123 TypeInfo::U8 => {
124 let bytes = input.read_slice_or_exit(size, c, exit);
125 let bytes_copy = bytes.to_vec(); let cast_vec: Vec<T> = unsafe { core::mem::transmute(bytes_copy) };
127 cast_vec
128 },
129 _ => {
130 let mut result: Vec<T> = Vec::with_capacity(size);
131 for _ in 0..size {
132 result.push(T::dep_decode_or_exit(input, c.clone(), exit));
133 }
134 result
135 },
136 }
137 }
138}
139
140impl NestedDecode for String {
141 fn dep_decode<I: NestedDecodeInput>(input: &mut I) -> Result<Self, DecodeError> {
142 let raw = Vec::<u8>::dep_decode(input)?;
143 match String::from_utf8(raw) {
144 Ok(s) => Ok(s),
145 Err(_) => Err(DecodeError::UTF8_DECODE_ERROR),
146 }
147 }
148
149 fn dep_decode_or_exit<I: NestedDecodeInput, ExitCtx: Clone>(
150 input: &mut I,
151 c: ExitCtx,
152 exit: fn(ExitCtx, DecodeError) -> !,
153 ) -> Self {
154 let raw = Vec::<u8>::dep_decode_or_exit(input, c.clone(), exit);
155 match String::from_utf8(raw) {
156 Ok(s) => s,
157 Err(_) => exit(c, DecodeError::UTF8_DECODE_ERROR),
158 }
159 }
160}
161
162impl NestedDecode for Box<str> {
163 #[inline]
164 fn dep_decode<I: NestedDecodeInput>(input: &mut I) -> Result<Self, DecodeError> {
165 Ok(String::dep_decode(input)?.into_boxed_str())
166 }
167
168 #[inline]
169 fn dep_decode_or_exit<I: NestedDecodeInput, ExitCtx: Clone>(
170 input: &mut I,
171 c: ExitCtx,
172 exit: fn(ExitCtx, DecodeError) -> !,
173 ) -> Self {
174 String::dep_decode_or_exit(input, c, exit).into_boxed_str()
175 }
176}
177
178macro_rules! decode_num_unsigned {
179 ($ty:ty, $num_bytes:expr, $type_info:expr) => {
180 impl NestedDecode for $ty {
181 const TYPE_INFO: TypeInfo = $type_info;
182
183 fn dep_decode<I: NestedDecodeInput>(input: &mut I) -> Result<Self, DecodeError> {
184 let bytes = input.read_slice($num_bytes)?;
185 let num = bytes_to_number(bytes, false) as $ty;
186 Ok(num)
187 }
188
189 fn dep_decode_or_exit<I: NestedDecodeInput, ExitCtx: Clone>(
190 input: &mut I,
191 c: ExitCtx,
192 exit: fn(ExitCtx, DecodeError) -> !,
193 ) -> Self {
194 let bytes = input.read_slice_or_exit($num_bytes, c, exit);
195 let num = bytes_to_number(bytes, false) as $ty;
196 num
197 }
198 }
199 };
200}
201
202decode_num_unsigned!(u16, 2, TypeInfo::U16);
203decode_num_unsigned!(u32, 4, TypeInfo::U32);
204decode_num_unsigned!(usize, 4, TypeInfo::USIZE);
205decode_num_unsigned!(u64, 8, TypeInfo::U64);
206
207macro_rules! decode_num_signed {
208 ($ty:ty, $num_bytes:expr, $type_info:expr) => {
209 impl NestedDecode for $ty {
210 const TYPE_INFO: TypeInfo = $type_info;
211
212 fn dep_decode<I: NestedDecodeInput>(input: &mut I) -> Result<Self, DecodeError> {
213 let bytes = input.read_slice($num_bytes)?;
214 let num = bytes_to_number(bytes, true) as $ty;
215 Ok(num)
216 }
217
218 fn dep_decode_or_exit<I: NestedDecodeInput, ExitCtx: Clone>(
219 input: &mut I,
220 c: ExitCtx,
221 exit: fn(ExitCtx, DecodeError) -> !,
222 ) -> Self {
223 let bytes = input.read_slice_or_exit($num_bytes, c, exit);
224 let num = bytes_to_number(bytes, true) as $ty;
225 num
226 }
227 }
228 };
229}
230
231decode_num_signed!(i8, 1, TypeInfo::I8);
232decode_num_signed!(i16, 2, TypeInfo::I16);
233decode_num_signed!(i32, 4, TypeInfo::I32);
234decode_num_signed!(isize, 4, TypeInfo::ISIZE);
235decode_num_signed!(i64, 8, TypeInfo::I64);
236
237impl NestedDecode for bool {
238 const TYPE_INFO: TypeInfo = TypeInfo::Bool;
239
240 fn dep_decode<I: NestedDecodeInput>(input: &mut I) -> Result<Self, DecodeError> {
241 match input.read_byte()? {
242 0 => Ok(false),
243 1 => Ok(true),
244 _ => Err(DecodeError::INVALID_VALUE),
245 }
246 }
247
248 fn dep_decode_or_exit<I: NestedDecodeInput, ExitCtx: Clone>(
249 input: &mut I,
250 c: ExitCtx,
251 exit: fn(ExitCtx, DecodeError) -> !,
252 ) -> Self {
253 match input.read_byte_or_exit(c.clone(), exit) {
254 0 => false,
255 1 => true,
256 _ => exit(c, DecodeError::INVALID_VALUE),
257 }
258 }
259}
260
261impl<T: NestedDecode> NestedDecode for Option<T> {
262 fn dep_decode<I: NestedDecodeInput>(input: &mut I) -> Result<Self, DecodeError> {
263 match input.read_byte()? {
264 0 => Ok(None),
265 1 => Ok(Some(T::dep_decode(input)?)),
266 _ => Err(DecodeError::INVALID_VALUE),
267 }
268 }
269
270 fn dep_decode_or_exit<I: NestedDecodeInput, ExitCtx: Clone>(
271 input: &mut I,
272 c: ExitCtx,
273 exit: fn(ExitCtx, DecodeError) -> !,
274 ) -> Self {
275 match input.read_byte_or_exit(c.clone(), exit) {
276 0 => None,
277 1 => Some(T::dep_decode_or_exit(input, c, exit)),
278 _ => exit(c, DecodeError::INVALID_VALUE),
279 }
280 }
281}
282
283impl<T: NestedDecode> NestedDecode for Box<T> {
284 fn dep_decode<I: NestedDecodeInput>(input: &mut I) -> Result<Self, DecodeError> {
285 Ok(Box::new(T::dep_decode(input)?))
286 }
287
288 fn dep_decode_or_exit<I: NestedDecodeInput, ExitCtx: Clone>(
289 input: &mut I,
290 c: ExitCtx,
291 exit: fn(ExitCtx, DecodeError) -> !,
292 ) -> Self {
293 Box::new(T::dep_decode_or_exit(input, c, exit))
294 }
295}
296
297macro_rules! tuple_impls {
298 ($($len:expr => ($($n:tt $name:ident)+))+) => {
299 $(
300 impl<$($name),+> NestedDecode for ($($name,)+)
301 where
302 $($name: NestedDecode,)+
303 {
304 fn dep_decode<I: NestedDecodeInput>(input: &mut I) -> Result<Self, DecodeError> {
305 Ok((
306 $(
307 $name::dep_decode(input)?,
308 )+
309 ))
310 }
311
312 fn dep_decode_or_exit<I: NestedDecodeInput, ExitCtx: Clone>(input: &mut I, c: ExitCtx, exit: fn(ExitCtx, DecodeError) -> !) -> Self {
313 (
314 $(
315 $name::dep_decode_or_exit(input, c.clone(), exit),
316 )+
317 )
318 }
319 }
320 )+
321 }
322}
323
324tuple_impls! {
325 1 => (0 T0)
326 2 => (0 T0 1 T1)
327 3 => (0 T0 1 T1 2 T2)
328 4 => (0 T0 1 T1 2 T2 3 T3)
329 5 => (0 T0 1 T1 2 T2 3 T3 4 T4)
330 6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5)
331 7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6)
332 8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7)
333 9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8)
334 10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9)
335 11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10)
336 12 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11)
337 13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12)
338 14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13)
339 15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14)
340 16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15)
341}
342
343macro_rules! array_impls {
344 ($($n: tt,)+) => {
345 $(
346 impl<T: NestedDecode> NestedDecode for [T; $n] {
347 fn dep_decode<I: NestedDecodeInput>(input: &mut I) -> Result<Self, DecodeError> {
348 let mut r = ArrayVec::new();
349 for _ in 0..$n {
350 r.push(T::dep_decode(input)?);
351 }
352 let i = r.into_inner();
353
354 match i {
355 Ok(a) => Ok(a),
356 Err(_) => Err(DecodeError::ARRAY_DECODE_ERROR),
357 }
358 }
359
360 fn dep_decode_or_exit<I: NestedDecodeInput, ExitCtx: Clone>(input: &mut I, c: ExitCtx, exit: fn(ExitCtx, DecodeError) -> !) -> Self {
361 let mut r = ArrayVec::new();
362 for _ in 0..$n {
363 r.push(T::dep_decode_or_exit(input, c.clone(), exit));
364 }
365 let i = r.into_inner();
366
367 match i {
368 Ok(a) => a,
369 Err(_) => exit(c, DecodeError::ARRAY_DECODE_ERROR),
370 }
371 }
372 }
373 )+
374 }
375}
376
377#[rustfmt::skip]
378array_impls!(
379 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
380 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
381 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
382 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
383 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
384 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
385 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
386 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140,
387 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156,
388 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172,
389 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188,
390 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204,
391 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220,
392 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236,
393 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252,
394 253, 254, 255, 256, 384, 512, 768, 1024, 2048, 4096, 8192, 16384, 32768,
395);
396
397impl NestedDecode for NonZeroUsize {
398 fn dep_decode<I: NestedDecodeInput>(input: &mut I) -> Result<Self, DecodeError> {
399 if let Some(nz) = NonZeroUsize::new(usize::dep_decode(input)?) {
400 Ok(nz)
401 } else {
402 Err(DecodeError::INVALID_VALUE)
403 }
404 }
405
406 fn dep_decode_or_exit<I: NestedDecodeInput, ExitCtx: Clone>(
407 input: &mut I,
408 c: ExitCtx,
409 exit: fn(ExitCtx, DecodeError) -> !,
410 ) -> Self {
411 if let Some(nz) = NonZeroUsize::new(usize::dep_decode_or_exit(input, c.clone(), exit)) {
412 nz
413 } else {
414 exit(c, DecodeError::INVALID_VALUE)
415 }
416 }
417}
418
419#[cfg(test)]
422mod tests {
423 use super::super::test_struct::*;
424 use super::*;
425 use crate::test_util::check_dep_decode;
426 use core::fmt::Debug;
427
428 fn deser_ok<V>(element: V, bytes: &[u8])
429 where
430 V: NestedDecode + PartialEq + Debug + 'static,
431 {
432 let input = bytes.to_vec();
433 let deserialized: V = check_dep_decode::<V>(&input[..]);
434 assert_eq!(deserialized, element);
435 }
436
437 #[test]
438 fn test_dep_decode_numbers() {
439 deser_ok(5u8, &[5]);
441 deser_ok(5u16, &[0, 5]);
442 deser_ok(5u32, &[0, 0, 0, 5]);
443 deser_ok(5usize, &[0, 0, 0, 5]);
444 deser_ok(5u64, &[0, 0, 0, 0, 0, 0, 0, 5]);
445 deser_ok(5i8, &[5]);
447 deser_ok(5i16, &[0, 5]);
448 deser_ok(5i32, &[0, 0, 0, 5]);
449 deser_ok(5isize, &[0, 0, 0, 5]);
450 deser_ok(5i64, &[0, 0, 0, 0, 0, 0, 0, 5]);
451 deser_ok(-5i8, &[251]);
453 deser_ok(-5i16, &[255, 251]);
454 deser_ok(-5i32, &[255, 255, 255, 251]);
455 deser_ok(-5isize, &[255, 255, 255, 251]);
456 deser_ok(-5i64, &[255, 255, 255, 255, 255, 255, 255, 251]);
457 deser_ok(NonZeroUsize::new(5).unwrap(), &[0, 0, 0, 5]);
459 }
460
461 #[test]
462 #[rustfmt::skip]
463 fn test_dep_decode_str() {
464 deser_ok(String::from("abc"), &[0, 0, 0, 3, b'a', b'b', b'c']);
465 deser_ok(String::from("abc").into_boxed_str(), &[0, 0, 0, 3, b'a', b'b', b'c']);
466 }
467
468 #[test]
469 fn test_struct() {
470 let test = Test {
471 int: 1,
472 seq: [5, 6].to_vec(),
473 another_byte: 7,
474 };
475 deser_ok(test, &[0, 1, 0, 0, 0, 2, 5, 6, 7]);
476 }
477
478 #[test]
479 fn test_enum() {
480 let u = E::Unit;
481 let expected: &[u8] = &[0, 0, 0, 0];
482 deser_ok(u, expected);
483
484 let n = E::Newtype(1);
485 let expected: &[u8] = &[0, 0, 0, 1, 0, 0, 0, 1];
486 deser_ok(n, expected);
487
488 let t = E::Tuple(1, 2);
489 let expected: &[u8] = &[
490 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0,
491 2, ];
493 deser_ok(t, expected);
494
495 let s = E::Struct { a: 1 };
496 let expected: &[u8] = &[0, 0, 0, 3, 0, 0, 0, 1];
497 deser_ok(s, expected);
498 }
499}