multiversx_sc_codec/impl_for_types/
impl_array.rs1use crate::{
2 DecodeError, DecodeErrorHandler, EncodeErrorHandler, NestedDecode, NestedDecodeInput,
3 NestedEncode, NestedEncodeOutput, TopDecode, TopDecodeInput, TopEncode, TopEncodeOutput,
4 top_decode_from_nested_or_handle_err,
5};
6use alloc::boxed::Box;
7use arrayvec::ArrayVec;
8
9impl<T: NestedEncode, const N: usize> NestedEncode for [T; N] {
10 #[inline]
11 fn dep_encode_or_handle_err<O, H>(&self, dest: &mut O, h: H) -> Result<(), H::HandledErr>
12 where
13 O: NestedEncodeOutput,
14 H: EncodeErrorHandler,
15 {
16 super::impl_slice::dep_encode_slice_contents(&self[..], dest, h)
17 }
18}
19
20impl<T: NestedEncode, const N: usize> TopEncode for [T; N] {
21 #[inline]
22 fn top_encode_or_handle_err<O, H>(&self, output: O, h: H) -> Result<(), H::HandledErr>
23 where
24 O: TopEncodeOutput,
25 H: EncodeErrorHandler,
26 {
27 (&self[..]).top_encode_or_handle_err(output, h)
29 }
30}
31
32impl<T: NestedDecode, const N: usize> NestedDecode for [T; N] {
33 #[allow(clippy::reversed_empty_ranges)]
34 fn dep_decode_or_handle_err<I, H>(input: &mut I, h: H) -> Result<Self, H::HandledErr>
35 where
36 I: NestedDecodeInput,
37 H: DecodeErrorHandler,
38 {
39 let mut r = ArrayVec::new();
40 for _ in 0..N {
41 r.push(T::dep_decode_or_handle_err(input, h)?);
42 }
43 let i = r.into_inner();
44
45 match i {
46 Ok(a) => Ok(a),
47 Err(_) => Err(h.handle_error(DecodeError::ARRAY_DECODE_ERROR)),
48 }
49 }
50}
51
52impl<T: NestedDecode, const N: usize> TopDecode for [T; N] {
53 fn top_decode_or_handle_err<I, H>(input: I, h: H) -> Result<Self, H::HandledErr>
54 where
55 I: TopDecodeInput,
56 H: DecodeErrorHandler,
57 {
58 top_decode_from_nested_or_handle_err(input, h)
59 }
60
61 fn top_decode_boxed_or_handle_err<I, H>(input: I, h: H) -> Result<Box<Self>, H::HandledErr>
62 where
63 I: TopDecodeInput,
64 H: DecodeErrorHandler,
65 {
66 T::if_u8(
67 input,
68 |input| {
69 let bs = input.into_boxed_slice_u8();
71 if bs.len() != N {
72 return Err(h.handle_error(DecodeError::ARRAY_DECODE_ERROR));
73 }
74 let raw = Box::into_raw(bs);
75 let array_box = unsafe { Box::<[T; N]>::from_raw(raw as *mut [T; N]) };
76 Ok(array_box)
77 },
78 |input| Ok(Box::new(Self::top_decode_or_handle_err(input, h)?)),
79 )
80 }
81}
82
83#[cfg(test)]
84mod tests {
85 use crate::test_util::{check_dep_encode_decode, check_top_encode, check_top_encode_decode};
86
87 use super::*;
88 use alloc::vec::Vec;
89
90 #[test]
91 fn test_array_16384() {
92 let arr = [7i32; 16384];
93 let mut expected_bytes = Vec::<u8>::with_capacity(16384 * 4);
94 for _ in 0..16384 {
95 expected_bytes.push(0);
96 expected_bytes.push(0);
97 expected_bytes.push(0);
98 expected_bytes.push(7);
99 }
100
101 let serialized_bytes = check_top_encode(&arr);
103 assert_eq!(serialized_bytes, expected_bytes);
104
105 let deserialized = <[i32; 16384]>::top_decode(&serialized_bytes[..]).unwrap();
107 for byte in deserialized {
108 assert_eq!(byte, 7i32);
109 }
110 }
111
112 #[test]
113 fn test_top_array_u8() {
114 check_top_encode_decode([1u8, 2u8, 3u8], &[1, 2, 3]);
115 }
116
117 #[test]
118 fn test_top_array_u8_empty() {
119 check_top_encode_decode([0u8; 0], &[]);
120 }
121
122 #[test]
123 fn test_top_array_i32() {
124 check_top_encode_decode([1i32, 2i32], &[0, 0, 0, 1, 0, 0, 0, 2]);
125 }
126
127 #[test]
128 fn test_dep_array_u8() {
129 check_dep_encode_decode([1u8, 2u8, 3u8], &[1, 2, 3]);
130 }
131
132 #[test]
133 fn test_dep_array_i32() {
134 check_dep_encode_decode([1i32, 2i32], &[0, 0, 0, 1, 0, 0, 0, 2]);
135 }
136
137 #[test]
138 fn test_top_array_32_bytes() {
139 let arr = [0xABu8; 32];
140 check_top_encode_decode(arr, &[0xAB; 32]);
141 }
142}