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