numbat_codec/
impl_array.rs

1use crate::codec_err::{DecodeError, EncodeError};
2use crate::nested_de::NestedDecode;
3use crate::nested_de_input::NestedDecodeInput;
4use crate::nested_ser::{
5    dep_encode_slice_contents, dep_encode_slice_contents_or_exit, NestedEncode,
6};
7use crate::nested_ser_output::NestedEncodeOutput;
8use crate::top_de::{top_decode_from_nested, top_decode_from_nested_or_exit, TopDecode};
9use crate::top_de_input::TopDecodeInput;
10use crate::top_ser::TopEncode;
11use crate::top_ser_output::TopEncodeOutput;
12use crate::TypeInfo;
13use alloc::boxed::Box;
14use arrayvec::ArrayVec;
15
16macro_rules! array_impls {
17    ($($n: tt,)+) => {
18        $(
19			impl<T: NestedEncode> NestedEncode for [T; $n] {
20				#[inline]
21				fn dep_encode<O: NestedEncodeOutput>(&self, dest: &mut O) -> Result<(), EncodeError> {
22					dep_encode_slice_contents(&self[..], dest)
23				}
24
25				#[inline]
26				fn dep_encode_or_exit<O: NestedEncodeOutput, ExitCtx: Clone>(&self, dest: &mut O, c: ExitCtx, exit: fn(ExitCtx, EncodeError) -> !) {
27					dep_encode_slice_contents_or_exit(&self[..], dest, c, exit);
28				}
29			}
30
31			impl<T: NestedEncode> TopEncode for [T; $n] {
32				#[inline]
33				fn top_encode<O: TopEncodeOutput>(&self, output: O) -> Result<(), EncodeError> {
34					// the top encoded slice does not serialize its length, so just like the array
35					(&self[..]).top_encode(output)
36				}
37
38				#[inline]
39				fn top_encode_or_exit<O: TopEncodeOutput, ExitCtx: Clone>(&self, output: O, c: ExitCtx, exit: fn(ExitCtx, EncodeError) -> !) {
40					(&self[..]).top_encode_or_exit(output, c, exit);
41				}
42            }
43
44			impl<T: NestedDecode> NestedDecode for [T; $n] {
45                #[allow(clippy::reversed_empty_ranges)]
46            	fn dep_decode<I: NestedDecodeInput>(input: &mut I) -> Result<Self, DecodeError> {
47					let mut r = ArrayVec::new();
48					for _ in 0..$n {
49						r.push(T::dep_decode(input)?);
50					}
51					let i = r.into_inner();
52
53					match i {
54						Ok(a) => Ok(a),
55						Err(_) => Err(DecodeError::ARRAY_DECODE_ERROR),
56					}
57                }
58
59                #[allow(clippy::reversed_empty_ranges)]
60            	fn dep_decode_or_exit<I: NestedDecodeInput, ExitCtx: Clone>(input: &mut I, c: ExitCtx, exit: fn(ExitCtx, DecodeError) -> !) -> Self {
61                    let mut r = ArrayVec::new();
62					for _ in 0..$n {
63						r.push(T::dep_decode_or_exit(input, c.clone(), exit));
64					}
65					let i = r.into_inner();
66
67					match i {
68						Ok(a) => a,
69						Err(_) => exit(c, DecodeError::ARRAY_DECODE_ERROR),
70					}
71                }
72            }
73
74			impl<T: NestedDecode> TopDecode for [T; $n] {
75                fn top_decode<I: TopDecodeInput>(input: I) -> Result<Self, DecodeError> {
76                    top_decode_from_nested(input)
77                }
78
79                fn top_decode_or_exit<I: TopDecodeInput, ExitCtx: Clone>(input: I, c: ExitCtx, exit: fn(ExitCtx, DecodeError) -> !) -> Self {
80                    top_decode_from_nested_or_exit(input, c, exit)
81                }
82
83                fn top_decode_boxed<I: TopDecodeInput>(input: I) -> Result<Box<Self>, DecodeError> {
84                    if let TypeInfo::U8 = T::TYPE_INFO {
85                        // transmute directly
86                        let bs = input.into_boxed_slice_u8();
87                        if bs.len() != $n {
88                            return Err(DecodeError::ARRAY_DECODE_ERROR);
89                        }
90                        let raw = Box::into_raw(bs);
91                        let array_box = unsafe { Box::<[T; $n]>::from_raw(raw as *mut [T; $n]) };
92                        Ok(array_box)
93                    } else {
94                        Ok(Box::new(Self::top_decode(input)?))
95                    }
96                }
97
98                fn top_decode_boxed_or_exit<I: TopDecodeInput, ExitCtx: Clone>(input: I, c: ExitCtx, exit: fn(ExitCtx, DecodeError) -> !) -> Box<Self> {
99                    if let TypeInfo::U8 = T::TYPE_INFO {
100                        // transmute directly
101                        let bs = input.into_boxed_slice_u8();
102                        if bs.len() != $n {
103                            exit(c, DecodeError::ARRAY_DECODE_ERROR);
104                        }
105                        let raw = Box::into_raw(bs);
106                        let array_box = unsafe { Box::<[T; $n]>::from_raw(raw as *mut [T; $n]) };
107                        array_box
108                    } else {
109                        Box::new(Self::top_decode_or_exit(input, c, exit))
110                    }
111                }
112            }
113        )+
114    }
115}
116
117#[rustfmt::skip]
118array_impls!(
119	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
120	17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
121	32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
122	52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
123	72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
124	92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
125	109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
126	125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140,
127	141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156,
128	157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172,
129	173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188,
130	189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204,
131	205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220,
132	221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236,
133	237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252,
134	253, 254, 255, 256, 384, 512, 768, 1024, 2048, 4096, 8192, 16384, 32768,
135);