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
390impl NestedEncode for NonZeroUsize {
391 #[inline]
392 fn dep_encode<O: NestedEncodeOutput>(&self, dest: &mut O) -> Result<(), EncodeError> {
393 self.get().dep_encode(dest)
394 }
395
396 #[inline]
397 fn dep_encode_or_exit<O: NestedEncodeOutput, ExitCtx: Clone>(
398 &self,
399 dest: &mut O,
400 c: ExitCtx,
401 exit: fn(ExitCtx, EncodeError) -> !,
402 ) {
403 self.get().dep_encode_or_exit(dest, c, exit);
404 }
405}
406
407#[cfg(test)]
410mod tests {
411 use super::super::test_struct::*;
412 use super::*;
413 use crate::test_util::check_dep_encode;
414 use core::fmt::Debug;
415
416 fn ser_ok<V>(element: V, expected_bytes: &[u8])
417 where
418 V: NestedEncode + PartialEq + Debug + 'static,
419 {
420 let bytes = check_dep_encode(&element);
421 assert_eq!(bytes.as_slice(), expected_bytes);
422 }
423
424 #[test]
425 fn test_dep_encode_numbers() {
426 ser_ok(5u8, &[5]);
428 ser_ok(5u16, &[0, 5]);
429 ser_ok(5u32, &[0, 0, 0, 5]);
430 ser_ok(5usize, &[0, 0, 0, 5]);
431 ser_ok(5u64, &[0, 0, 0, 0, 0, 0, 0, 5]);
432 ser_ok(5i8, &[5]);
434 ser_ok(5i16, &[0, 5]);
435 ser_ok(5i32, &[0, 0, 0, 5]);
436 ser_ok(5isize, &[0, 0, 0, 5]);
437 ser_ok(5i64, &[0, 0, 0, 0, 0, 0, 0, 5]);
438 ser_ok(-5i8, &[251]);
440 ser_ok(-5i16, &[255, 251]);
441 ser_ok(-5i32, &[255, 255, 255, 251]);
442 ser_ok(-5isize, &[255, 255, 255, 251]);
443 ser_ok(-5i64, &[255, 255, 255, 255, 255, 255, 255, 251]);
444 ser_ok(NonZeroUsize::new(5).unwrap(), &[0, 0, 0, 5]);
446 }
447
448 #[test]
449 fn test_dep_encode_bool() {
450 ser_ok(true, &[1]);
451 ser_ok(false, &[0]);
452 }
453
454 #[test]
455 fn test_dep_encode_empty_bytes() {
456 let empty_byte_slice: &[u8] = &[];
457 ser_ok(empty_byte_slice, &[0, 0, 0, 0]);
458 }
459
460 #[test]
461 fn test_dep_encode_bytes() {
462 ser_ok(&[1u8, 2u8, 3u8][..], &[0, 0, 0, 3, 1u8, 2u8, 3u8]);
463 }
464
465 #[test]
466 fn test_dep_encode_vec_u8() {
467 let some_vec = [1u8, 2u8, 3u8].to_vec();
468 ser_ok(some_vec, &[0, 0, 0, 3, 1u8, 2u8, 3u8]);
469 }
470
471 #[test]
472 #[rustfmt::skip]
473 fn test_dep_encode_str() {
474 let s = "abc";
475 ser_ok(s, &[0, 0, 0, 3, b'a', b'b', b'c']);
476 ser_ok(String::from(s), &[0, 0, 0, 3, b'a', b'b', b'c']);
477 ser_ok(String::from(s).into_boxed_str(), &[0, 0, 0, 3, b'a', b'b', b'c']);
478 }
479
480 #[test]
481 fn test_dep_encode_vec_i32() {
482 let some_vec = [1i32, 2i32, 3i32].to_vec();
483 let expected: &[u8] = &[0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3];
484 ser_ok(some_vec, expected);
485 }
486
487 #[test]
488 fn test_struct() {
489 let test = Test {
490 int: 1,
491 seq: [5, 6].to_vec(),
492 another_byte: 7,
493 };
494
495 ser_ok(test, &[0, 1, 0, 0, 0, 2, 5, 6, 7]);
496 }
497
498 #[test]
499 fn test_tuple() {
500 ser_ok((7u32, -2i16), &[0, 0, 0, 7, 255, 254]);
501 }
502
503 #[test]
504 fn test_unit() {
505 ser_ok((), &[]);
506 }
507
508 #[test]
509 fn test_enum() {
510 let u = E::Unit;
511 let expected: &[u8] = &[0, 0, 0, 0];
512 ser_ok(u, expected);
513
514 let n = E::Newtype(1);
515 let expected: &[u8] = &[0, 0, 0, 1, 0, 0, 0, 1];
516 ser_ok(n, expected);
517
518 let t = E::Tuple(1, 2);
519 let expected: &[u8] = &[
520 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0,
521 2, ];
523 ser_ok(t, expected);
524
525 let s = E::Struct { a: 1 };
526 let expected: &[u8] = &[0, 0, 0, 3, 0, 0, 0, 1];
527 ser_ok(s, expected);
528 }
529}