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