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