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