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
401impl TopDecode for NonZeroUsize {
402 fn top_decode<I: TopDecodeInput>(input: I) -> Result<Self, DecodeError> {
403 if let Some(nz) = NonZeroUsize::new(usize::top_decode(input)?) {
404 Ok(nz)
405 } else {
406 Err(DecodeError::INVALID_VALUE)
407 }
408 }
409
410 fn top_decode_or_exit<I: TopDecodeInput, ExitCtx: Clone>(
411 input: I,
412 c: ExitCtx,
413 exit: fn(ExitCtx, DecodeError) -> !,
414 ) -> Self {
415 if let Some(nz) = NonZeroUsize::new(usize::top_decode_or_exit(input, c.clone(), exit)) {
416 nz
417 } else {
418 exit(c, DecodeError::INVALID_VALUE)
419 }
420 }
421}
422
423#[cfg(test)]
426mod tests {
427 use super::super::test_struct::*;
428 use super::*;
429 use crate::test_util::check_top_decode;
430 use core::fmt::Debug;
431
432 fn deser_ok<V>(element: V, bytes: &[u8])
433 where
434 V: TopDecode + PartialEq + Debug + 'static,
435 {
436 let deserialized: V = check_top_decode::<V>(&bytes[..]);
437 assert_eq!(deserialized, element);
438 }
439
440 #[test]
441 fn test_top_numbers_decompacted() {
442 deser_ok(5u8, &[5]);
444 deser_ok(5u16, &[5]);
445 deser_ok(5u32, &[5]);
446 deser_ok(5u64, &[5]);
447 deser_ok(5usize, &[5]);
448 deser_ok(5i8, &[5]);
450 deser_ok(5i16, &[5]);
451 deser_ok(5i32, &[5]);
452 deser_ok(5i64, &[5]);
453 deser_ok(5isize, &[5]);
454 deser_ok(-5i8, &[251]);
456 deser_ok(-5i16, &[251]);
457 deser_ok(-5i32, &[251]);
458 deser_ok(-5i64, &[251]);
459 deser_ok(-5isize, &[251]);
460 deser_ok(NonZeroUsize::new(5).unwrap(), &[5]);
462 }
463
464 #[test]
465 fn test_top_numbers_decompacted_2() {
466 deser_ok(-1i32, &[255]);
467 deser_ok(-1i32, &[255, 255]);
468 deser_ok(-1i32, &[255, 255, 255, 255]);
469 deser_ok(-1i64, &[255, 255, 255, 255, 255, 255, 255, 255]);
470 }
471
472 #[test]
473 fn test_top_decode_str() {
474 deser_ok(String::from("abc"), &[b'a', b'b', b'c']);
475 deser_ok(String::from("abc").into_boxed_str(), &[b'a', b'b', b'c']);
476 }
477
478 #[test]
479 fn test_struct() {
480 let test = Test {
481 int: 1,
482 seq: [5, 6].to_vec(),
483 another_byte: 7,
484 };
485 deser_ok(test, &[0, 1, 0, 0, 0, 2, 5, 6, 7]);
486 }
487
488 #[test]
489 fn test_enum() {
490 let u = E::Unit;
491 let expected: &[u8] = &[0, 0, 0, 0];
492 deser_ok(u, expected);
493
494 let n = E::Newtype(1);
495 let expected: &[u8] = &[0, 0, 0, 1, 0, 0, 0, 1];
496 deser_ok(n, expected);
497
498 let t = E::Tuple(1, 2);
499 let expected: &[u8] = &[
500 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0,
501 2, ];
503 deser_ok(t, expected);
504
505 let s = E::Struct { a: 1 };
506 let expected: &[u8] = &[0, 0, 0, 3, 0, 0, 0, 1];
507 deser_ok(s, expected);
508 }
509}