1#![no_std]
2
3extern crate alloc;
4
5#[cfg(feature = "numbat-codec-derive")]
6pub use numbat_codec_derive;
7
8pub use alloc::vec::Vec;
10
11mod codec_err;
12mod default_traits;
13mod impl_array;
14mod nested_de;
15mod nested_de_input;
16mod nested_ser;
17mod nested_ser_output;
18mod num_conv;
19pub mod test_util;
20mod top_de;
21mod top_de_input;
22mod top_ser;
23mod top_ser_output;
24mod transmute;
25
26pub use crate::nested_de_input::NestedDecodeInput;
27pub use crate::nested_ser_output::NestedEncodeOutput;
28pub use crate::num_conv::{bytes_to_number, top_encode_number_to_output, using_encoded_number};
29pub use codec_err::{DecodeError, EncodeError};
30pub use default_traits::{DecodeDefault, EncodeDefault};
31pub use nested_de::{dep_decode_from_byte_slice, dep_decode_from_byte_slice_or_exit, NestedDecode};
32pub use nested_ser::{dep_encode_to_vec, NestedEncode, NestedEncodeNoErr};
33pub use top_de::{top_decode_from_nested, top_decode_from_nested_or_exit, TopDecode};
34pub use top_de_input::TopDecodeInput;
35pub use top_ser::{
36 top_encode_from_nested, top_encode_from_nested_or_exit, top_encode_no_err, top_encode_to_vec,
37 TopEncode,
38};
39pub use top_ser_output::TopEncodeOutput;
40pub use transmute::{boxed_slice_into_vec, vec_into_boxed_slice};
41
42#[doc(hidden)]
46#[allow(clippy::upper_case_acronyms)]
47pub enum TypeInfo {
48 Unknown,
50 U8,
51 I8,
52 U16,
53 I16,
54 U32,
55 I32,
56 USIZE,
57 ISIZE,
58 U64,
59 I64,
60 Bool,
61 BigUint,
62 BigInt,
63 Unit,
64}
65
66#[cfg(test)]
68pub mod test_struct {
69 use super::*;
70 use alloc::vec::Vec;
71 use core::fmt::Debug;
72
73 #[derive(PartialEq, Debug)]
74 pub struct Test {
75 pub int: u16,
76 pub seq: Vec<u8>,
77 pub another_byte: u8,
78 }
79
80 impl NestedEncode for Test {
81 fn dep_encode<O: NestedEncodeOutput>(&self, dest: &mut O) -> Result<(), EncodeError> {
82 self.int.dep_encode(dest)?;
83 self.seq.dep_encode(dest)?;
84 self.another_byte.dep_encode(dest)?;
85 Ok(())
86 }
87
88 fn dep_encode_or_exit<O: NestedEncodeOutput, ExitCtx: Clone>(
89 &self,
90 dest: &mut O,
91 c: ExitCtx,
92 exit: fn(ExitCtx, EncodeError) -> !,
93 ) {
94 self.int.dep_encode_or_exit(dest, c.clone(), exit);
95 self.seq.dep_encode_or_exit(dest, c.clone(), exit);
96 self.another_byte.dep_encode_or_exit(dest, c.clone(), exit);
97 }
98 }
99
100 impl TopEncode for Test {
101 #[inline]
102 fn top_encode<O: TopEncodeOutput>(&self, output: O) -> Result<(), EncodeError> {
103 top_encode_from_nested(self, output)
104 }
105
106 #[inline]
107 fn top_encode_or_exit<O: TopEncodeOutput, ExitCtx: Clone>(
108 &self,
109 output: O,
110 c: ExitCtx,
111 exit: fn(ExitCtx, EncodeError) -> !,
112 ) {
113 top_encode_from_nested_or_exit(self, output, c, exit);
114 }
115 }
116
117 impl NestedDecode for Test {
118 fn dep_decode<I: NestedDecodeInput>(input: &mut I) -> Result<Self, DecodeError> {
119 Ok(Test {
120 int: u16::dep_decode(input)?,
121 seq: Vec::<u8>::dep_decode(input)?,
122 another_byte: u8::dep_decode(input)?,
123 })
124 }
125
126 fn dep_decode_or_exit<I: NestedDecodeInput, ExitCtx: Clone>(
127 input: &mut I,
128 c: ExitCtx,
129 exit: fn(ExitCtx, DecodeError) -> !,
130 ) -> Self {
131 Test {
132 int: u16::dep_decode_or_exit(input, c.clone(), exit),
133 seq: Vec::<u8>::dep_decode_or_exit(input, c.clone(), exit),
134 another_byte: u8::dep_decode_or_exit(input, c.clone(), exit),
135 }
136 }
137 }
138
139 impl TopDecode for Test {
140 fn top_decode<I: TopDecodeInput>(input: I) -> Result<Self, DecodeError> {
141 top_decode_from_nested(input)
142 }
143
144 fn top_decode_or_exit<I: TopDecodeInput, ExitCtx: Clone>(
145 input: I,
146 c: ExitCtx,
147 exit: fn(ExitCtx, DecodeError) -> !,
148 ) -> Self {
149 top_decode_from_nested_or_exit(input, c, exit)
150 }
151 }
152
153 #[derive(PartialEq, Clone, Debug)]
154 pub enum E {
155 Unit,
156 Newtype(u32),
157 Tuple(u32, u32),
158 Struct { a: u32 },
159 }
160
161 impl NestedEncodeNoErr for E {
162 fn dep_encode_no_err<O: NestedEncodeOutput>(&self, dest: &mut O) {
163 match self {
164 E::Unit => {
165 0u32.dep_encode_no_err(dest);
166 },
167 E::Newtype(arg1) => {
168 1u32.dep_encode_no_err(dest);
169 arg1.dep_encode_no_err(dest);
170 },
171 E::Tuple(arg1, arg2) => {
172 2u32.dep_encode_no_err(dest);
173 arg1.dep_encode_no_err(dest);
174 arg2.dep_encode_no_err(dest);
175 },
176 E::Struct { a } => {
177 3u32.dep_encode_no_err(dest);
178 a.dep_encode_no_err(dest);
179 },
180 }
181 }
182 }
183
184 impl NestedEncode for E {
185 #[inline]
186 fn dep_encode<O: NestedEncodeOutput>(&self, dest: &mut O) -> Result<(), EncodeError> {
187 self.dep_encode_no_err(dest);
188 Ok(())
189 }
190
191 #[inline]
192 fn dep_encode_or_exit<O: NestedEncodeOutput, ExitCtx: Clone>(
193 &self,
194 dest: &mut O,
195 _: ExitCtx,
196 _: fn(ExitCtx, EncodeError) -> !,
197 ) {
198 self.dep_encode_no_err(dest);
199 }
200 }
201
202 impl TopEncode for E {
203 #[inline]
204 fn top_encode<O: TopEncodeOutput>(&self, output: O) -> Result<(), EncodeError> {
205 top_encode_from_nested(self, output)
206 }
207
208 #[inline]
209 fn top_encode_or_exit<O: TopEncodeOutput, ExitCtx: Clone>(
210 &self,
211 output: O,
212 c: ExitCtx,
213 exit: fn(ExitCtx, EncodeError) -> !,
214 ) {
215 top_encode_from_nested_or_exit(self, output, c, exit);
216 }
217 }
218
219 impl NestedDecode for E {
220 fn dep_decode<I: NestedDecodeInput>(input: &mut I) -> Result<Self, DecodeError> {
221 match u32::dep_decode(input)? {
222 0 => Ok(E::Unit),
223 1 => Ok(E::Newtype(u32::dep_decode(input)?)),
224 2 => Ok(E::Tuple(u32::dep_decode(input)?, u32::dep_decode(input)?)),
225 3 => Ok(E::Struct {
226 a: u32::dep_decode(input)?,
227 }),
228 _ => Err(DecodeError::INVALID_VALUE),
229 }
230 }
231
232 fn dep_decode_or_exit<I: NestedDecodeInput, ExitCtx: Clone>(
233 input: &mut I,
234 c: ExitCtx,
235 exit: fn(ExitCtx, DecodeError) -> !,
236 ) -> Self {
237 match u32::dep_decode_or_exit(input, c.clone(), exit) {
238 0 => E::Unit,
239 1 => E::Newtype(u32::dep_decode_or_exit(input, c.clone(), exit)),
240 2 => E::Tuple(
241 u32::dep_decode_or_exit(input, c.clone(), exit),
242 u32::dep_decode_or_exit(input, c.clone(), exit),
243 ),
244 3 => E::Struct {
245 a: u32::dep_decode_or_exit(input, c.clone(), exit),
246 },
247 _ => exit(c.clone(), DecodeError::INVALID_VALUE),
248 }
249 }
250 }
251
252 impl TopDecode for E {
253 fn top_decode<I: TopDecodeInput>(input: I) -> Result<Self, DecodeError> {
254 top_decode_from_nested(input)
255 }
256
257 fn top_decode_or_exit<I: TopDecodeInput, ExitCtx: Clone>(
258 input: I,
259 c: ExitCtx,
260 exit: fn(ExitCtx, DecodeError) -> !,
261 ) -> Self {
262 top_decode_from_nested_or_exit(input, c, exit)
263 }
264 }
265
266 #[derive(PartialEq, Debug, Clone, Copy)]
267 pub struct WrappedArray(pub [u8; 5]);
268
269 impl NestedEncode for WrappedArray {
270 fn dep_encode<O: NestedEncodeOutput>(&self, dest: &mut O) -> Result<(), EncodeError> {
271 dest.write(&self.0[..]);
272 Ok(())
273 }
274
275 fn dep_encode_or_exit<O: NestedEncodeOutput, ExitCtx: Clone>(
276 &self,
277 dest: &mut O,
278 _: ExitCtx,
279 _: fn(ExitCtx, EncodeError) -> !,
280 ) {
281 dest.write(&self.0[..]);
282 }
283 }
284
285 impl TopEncode for WrappedArray {
286 fn top_encode<O: TopEncodeOutput>(&self, output: O) -> Result<(), EncodeError> {
287 output.set_slice_u8(&self.0[..]);
288 Ok(())
289 }
290
291 fn top_encode_or_exit<O: TopEncodeOutput, ExitCtx: Clone>(
292 &self,
293 output: O,
294 _: ExitCtx,
295 _: fn(ExitCtx, EncodeError) -> !,
296 ) {
297 output.set_slice_u8(&self.0[..]);
298 }
299 }
300
301 impl NestedDecode for WrappedArray {
302 fn dep_decode<I: NestedDecodeInput>(input: &mut I) -> Result<Self, DecodeError> {
303 let mut arr = [0u8; 5];
304 input.read_into(&mut arr)?;
305 Ok(WrappedArray(arr))
306 }
307
308 fn dep_decode_or_exit<I: NestedDecodeInput, ExitCtx: Clone>(
309 input: &mut I,
310 c: ExitCtx,
311 exit: fn(ExitCtx, DecodeError) -> !,
312 ) -> Self {
313 let mut arr = [0u8; 5];
314 input.read_into_or_exit(&mut arr, c, exit);
315 WrappedArray(arr)
316 }
317 }
318
319 impl TopDecode for WrappedArray {
320 fn top_decode<I: TopDecodeInput>(input: I) -> Result<Self, DecodeError> {
321 top_decode_from_nested(input)
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 top_decode_from_nested_or_exit(input, c, exit)
330 }
331 }
332}
333
334#[cfg(test)]
335pub mod tests {
336 use super::test_struct::*;
337 use super::*;
338 use crate::test_util::{check_top_decode, check_top_encode, ser_deser_ok};
339 use alloc::vec::Vec;
340 use core::fmt::Debug;
341 use core::num::NonZeroUsize;
342
343 pub fn the_same<V>(element: V)
344 where
345 V: TopEncode + TopDecode + PartialEq + Debug + 'static,
346 {
347 let serialized_bytes = check_top_encode(&element);
348 let deserialized: V = check_top_decode::<V>(&serialized_bytes[..]);
349 assert_eq!(deserialized, element);
350 }
351
352 #[test]
353 fn test_top_compacted_numbers() {
354 ser_deser_ok(0u8, &[]);
356 ser_deser_ok(0u16, &[]);
357 ser_deser_ok(0u32, &[]);
358 ser_deser_ok(0u64, &[]);
359 ser_deser_ok(0usize, &[]);
360 ser_deser_ok(5u8, &[5]);
362 ser_deser_ok(5u16, &[5]);
363 ser_deser_ok(5u32, &[5]);
364 ser_deser_ok(5u64, &[5]);
365 ser_deser_ok(5usize, &[5]);
366 ser_deser_ok(5i8, &[5]);
368 ser_deser_ok(5i16, &[5]);
369 ser_deser_ok(5i32, &[5]);
370 ser_deser_ok(5i64, &[5]);
371 ser_deser_ok(5isize, &[5]);
372 ser_deser_ok(-5i8, &[251]);
374 ser_deser_ok(-5i16, &[251]);
375 ser_deser_ok(-5i32, &[251]);
376 ser_deser_ok(-5i64, &[251]);
377 ser_deser_ok(-5isize, &[251]);
378 ser_deser_ok(NonZeroUsize::new(5).unwrap(), &[5]);
380 }
381
382 #[test]
383 fn test_top_compacted_bool() {
384 ser_deser_ok(true, &[1]);
385 ser_deser_ok(false, &[]);
386 }
387
388 #[test]
389 fn test_top_bytes_compacted() {
390 ser_deser_ok(Vec::<u8>::new(), &[]);
391 ser_deser_ok([1u8, 2u8, 3u8].to_vec(), &[1u8, 2u8, 3u8]);
392 }
393
394 #[test]
395 fn test_vec_i32_compacted() {
396 let v = [1i32, 2i32, 3i32].to_vec();
397 let expected: &[u8] = &[0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3];
398 ser_deser_ok(v, expected);
399 }
400
401 #[test]
402 fn test_array_16384() {
403 let arr = [7i32; 16384];
404 let mut expected_bytes = Vec::<u8>::with_capacity(16384 * 4);
405 for _ in 0..16384 {
406 expected_bytes.push(0);
407 expected_bytes.push(0);
408 expected_bytes.push(0);
409 expected_bytes.push(7);
410 }
411
412 let serialized_bytes = check_top_encode(&arr);
414 assert_eq!(serialized_bytes, expected_bytes);
415
416 let deserialized = <[i32; 16384]>::top_decode(&serialized_bytes[..]).unwrap();
418 for i in 0..16384 {
419 assert_eq!(deserialized[i], 7i32);
420 }
421 }
422
423 #[test]
424 fn test_option_vec_i32() {
425 let some_v = Some([1i32, 2i32, 3i32].to_vec());
426 let expected: &[u8] = &[
427 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0,
428 0, 3,
429 ];
430 ser_deser_ok(some_v, expected);
431
432 let none_v: Option<Vec<i32>> = None;
433 ser_deser_ok(none_v, &[]);
434 }
435
436 #[test]
437 fn test_struct() {
438 let test = Test {
439 int: 1,
440 seq: [5, 6].to_vec(),
441 another_byte: 7,
442 };
443 the_same(test);
444 }
445
446 #[test]
447 fn test_wrapped_array() {
448 let wa = WrappedArray([1, 2, 3, 4, 5]);
449 ser_deser_ok(wa, &[1, 2, 3, 4, 5]);
450
451 let mut v: Vec<WrappedArray> = Vec::new();
452 v.push(wa);
453 v.push(WrappedArray([6, 7, 8, 9, 0]));
454 ser_deser_ok(v, &[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
455 }
456
457 #[test]
458 fn test_tuple() {
459 let t = (1i8, 2u32, 3i16);
460 let expected: &[u8] = &[1, 0, 0, 0, 2, 0, 3];
461 ser_deser_ok(t, expected);
462 }
463}