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