1use crate::{
2 alloc::string::ToString,
3 bytes_codec::{read_bytes, read_bytes_header, write_bytes_solidity, write_bytes_wasm},
4 encoder::{align_up, read_u32_aligned, write_u32_aligned, Encoder},
5 error::{CodecError, DecodingError},
6};
7use alloc::vec::Vec;
8use byteorder::ByteOrder;
9use bytes::{Buf, BytesMut};
10
11impl<T, B: ByteOrder, const ALIGN: usize> Encoder<B, ALIGN, false, false> for Vec<T>
28where
29 T: Default + Sized + Encoder<B, ALIGN, false, false> + alloc::fmt::Debug,
30{
31 const HEADER_SIZE: usize = core::mem::size_of::<u32>() * 3;
32 const IS_DYNAMIC: bool = true;
33
34 fn encode(&self, buf: &mut BytesMut, offset: usize) -> Result<(), CodecError> {
35 let aligned_elem_size = align_up::<ALIGN>(4);
36 let aligned_header_size = aligned_elem_size * 3;
37
38 if buf.len() < offset + aligned_header_size {
40 buf.resize(offset + aligned_header_size, 0);
41 }
42
43 write_u32_aligned::<B, ALIGN>(buf, offset, self.len() as u32);
45
46 if self.is_empty() {
47 write_u32_aligned::<B, ALIGN>(
49 buf,
50 offset + aligned_elem_size,
51 aligned_header_size as u32,
52 );
53 write_u32_aligned::<B, ALIGN>(buf, offset + aligned_elem_size * 2, 0);
54 return Ok(());
55 }
56
57 let mut value_encoder = BytesMut::zeroed(ALIGN.max(T::HEADER_SIZE) * self.len());
59 for (index, obj) in self.iter().enumerate() {
60 let elem_offset = ALIGN.max(T::HEADER_SIZE) * index;
61 obj.encode(&mut value_encoder, elem_offset)?;
62 }
63
64 let data = value_encoder.freeze();
65 write_bytes_wasm::<B, ALIGN>(buf, offset + aligned_elem_size, &data);
66
67 Ok(())
68 }
69
70 fn decode(buf: &impl Buf, offset: usize) -> Result<Self, CodecError> {
71 let aligned_header_el_size = align_up::<ALIGN>(4);
72
73 if buf.remaining() < offset + aligned_header_el_size {
74 return Err(CodecError::Decoding(DecodingError::BufferTooSmall {
75 expected: offset + aligned_header_el_size,
76 found: buf.remaining(),
77 msg: "failed to decode vector length".to_string(),
78 }));
79 }
80
81 let data_len = read_u32_aligned::<B, ALIGN>(buf, offset)? as usize;
82 if data_len == 0 {
83 return Ok(Vec::new());
84 }
85
86 let mut result = Vec::with_capacity(data_len);
87 let data = read_bytes::<B, ALIGN, false>(buf, offset + aligned_header_el_size)?;
88
89 for i in 0..data_len {
90 let elem_offset = i * align_up::<ALIGN>(T::HEADER_SIZE);
91 let value = T::decode(&data, elem_offset)?;
92 result.push(value);
93 }
94
95 Ok(result)
96 }
97
98 fn partial_decode(buf: &impl Buf, offset: usize) -> Result<(usize, usize), CodecError> {
99 read_bytes_header::<B, ALIGN, false>(buf, offset)
100 }
101}
102
103impl<T, B: ByteOrder, const ALIGN: usize> Encoder<B, ALIGN, true, false> for Vec<T>
105where
106 T: Default + Sized + Encoder<B, ALIGN, true, false> + alloc::fmt::Debug,
107{
108 const HEADER_SIZE: usize = 32;
109 const IS_DYNAMIC: bool = true;
110
111 fn encode(&self, buf: &mut BytesMut, offset: usize) -> Result<(), CodecError> {
112 if buf.len() < offset + Self::HEADER_SIZE {
114 buf.resize(offset + Self::HEADER_SIZE, 0);
115 }
116
117 write_u32_aligned::<B, ALIGN>(buf, offset, buf.len() as u32);
119
120 if self.is_empty() {
121 write_u32_aligned::<B, ALIGN>(buf, buf.len(), 0);
123 return Ok(());
124 }
125
126 let mut value_encoder = BytesMut::zeroed(32 * self.len());
128 for (index, obj) in self.iter().enumerate() {
129 let elem_offset = ALIGN.max(T::HEADER_SIZE) * index;
130 obj.encode(&mut value_encoder, elem_offset)?;
131 }
132
133 let data = value_encoder.freeze();
134 write_bytes_solidity::<B, ALIGN>(buf, offset + Self::HEADER_SIZE, &data, self.len() as u32);
135
136 Ok(())
137 }
138
139 fn decode(buf: &impl Buf, offset: usize) -> Result<Self, CodecError> {
140 let data_offset = read_u32_aligned::<B, ALIGN>(buf, offset)?;
141 let data_len = read_u32_aligned::<B, ALIGN>(buf, data_offset as usize)? as usize;
142
143 if data_len == 0 {
144 return Ok(Vec::new());
145 }
146
147 let mut result = Vec::with_capacity(data_len);
148 let chunk = &buf.chunk()[(data_offset + 32) as usize..];
149
150 for i in 0..data_len {
151 let elem_offset = i * align_up::<ALIGN>(T::HEADER_SIZE);
152 let value = T::decode(&chunk, elem_offset)?;
153 result.push(value);
154 }
155
156 Ok(result)
157 }
158
159 fn partial_decode(buf: &impl Buf, offset: usize) -> Result<(usize, usize), CodecError> {
160 read_bytes_header::<B, ALIGN, true>(buf, offset)
161 }
162}
163
164#[cfg(test)]
165mod tests {
166 use super::*;
167 use byteorder::{BigEndian, LittleEndian};
168 use bytes::{Bytes, BytesMut};
169
170 #[test]
171 fn test_empty_vec_u32() {
172 let original: Vec<u32> = Vec::new();
173 let mut buf = BytesMut::new();
174
175 <Vec<u32> as Encoder<LittleEndian, 4, false, false>>::encode(&original, &mut buf, 0)
176 .unwrap();
177 let encoded = buf.freeze();
178 let expected = hex::decode("000000000c00000000000000").expect("Failed to decode hex");
179 assert_eq!(encoded, Bytes::from(expected));
180
181 let decoded =
182 <Vec<u32> as Encoder<LittleEndian, 4, false, false>>::decode(&encoded, 0).unwrap();
183
184 assert_eq!(original, decoded);
185 }
186
187 #[test]
188 fn test_vec_u32_simple() {
189 let original: Vec<u32> = vec![1, 2, 3, 4, 5];
190 let mut buf = BytesMut::new();
191
192 <Vec<u32> as Encoder<BigEndian, 4, false, false>>::encode(&original, &mut buf, 0).unwrap();
193 let encoded = buf.freeze();
194
195 let expected_encoded = "000000050000000c000000140000000100000002000000030000000400000005";
196 assert_eq!(hex::encode(&encoded), expected_encoded);
197
198 let decoded =
199 <Vec<u32> as Encoder<BigEndian, 4, false, false>>::decode(&encoded, 0).unwrap();
200
201 assert_eq!(original, decoded);
202 }
203
204 #[test]
205 fn test_vec_u32_with_offset() {
206 let original: Vec<u32> = vec![1, 2, 3, 4, 5];
207 let mut buf = BytesMut::new();
208 buf.extend_from_slice(&[0xFF, 0xFF, 0xFF]); <Vec<u32> as Encoder<LittleEndian, 4, false, false>>::encode(&original, &mut buf, 3)
211 .unwrap();
212 let encoded = buf.freeze();
213
214 let decoded =
215 <Vec<u32> as Encoder<LittleEndian, 4, false, false>>::decode(&encoded, 3).unwrap();
216
217 assert_eq!(original, decoded);
218 }
219
220 #[test]
221 fn test_vec_u8_with_offset() {
222 let original: Vec<u8> = vec![1, 2, 3, 4, 5];
223 let mut buf = BytesMut::new();
224 buf.extend_from_slice(&[0xFF, 0xFF, 0xFF]); <Vec<u8> as Encoder<LittleEndian, 4, false, false>>::encode(&original, &mut buf, 3)
227 .unwrap();
228 let encoded = buf.freeze();
229
230 let decoded =
231 <Vec<u8> as Encoder<LittleEndian, 4, false, false>>::decode(&encoded, 3).unwrap();
232
233 assert_eq!(original, decoded);
234 }
235
236 #[test]
237 fn test_nested_vec_le_a2() {
238 let original: Vec<Vec<u16>> = vec![vec![3, 4], vec![5, 6, 7]];
239
240 let mut buf = BytesMut::new();
241 <Vec<Vec<u16>> as Encoder<LittleEndian, 2, false, false>>::encode(&original, &mut buf, 0)
242 .unwrap();
243 let encoded = buf.freeze();
244
245 let expected_encoded = "020000000c00000022000000020000001800000004000000030000001c0000000600000003000400050006000700";
246
247 assert_eq!(hex::encode(&encoded), expected_encoded);
248
249 let decoded =
250 <Vec<Vec<u16>> as Encoder<LittleEndian, 2, false, false>>::decode(&encoded, 0).unwrap();
251
252 assert_eq!(original, decoded);
253 }
254
255 #[test]
256 fn test_nested_vec_a4_le() {
257 let original: Vec<Vec<u16>> = vec![vec![3, 4], vec![5, 6, 7]];
258
259 let mut buf = BytesMut::new();
260 <Vec<Vec<u16>> as Encoder<LittleEndian, 4, false, false>>::encode(&original, &mut buf, 0)
261 .unwrap();
262 let encoded = buf.freeze();
263 let decoded =
264 <Vec<Vec<u16>> as Encoder<LittleEndian, 4, false, false>>::decode(&encoded, 0).unwrap();
265
266 assert_eq!(original, decoded);
267 }
268
269 #[test]
270 fn test_nested_vec_a4_be() {
271 let original: Vec<Vec<u16>> = vec![vec![3, 4], vec![5, 6, 7]];
272
273 let mut buf = BytesMut::new();
274 <Vec<Vec<u16>> as Encoder<BigEndian, 4, false, false>>::encode(&original, &mut buf, 0)
275 .unwrap();
276 let encoded = buf.freeze();
277
278 let decoded =
279 <Vec<Vec<u16>> as Encoder<BigEndian, 4, false, false>>::decode(&encoded, 0).unwrap();
280
281 assert_eq!(original, decoded);
282 }
283
284 #[test]
285 fn test_large_vec() {
286 let original: Vec<u64> = (0..1000).collect();
287 let mut buf = BytesMut::new();
288
289 <Vec<u64> as Encoder<BigEndian, 8, false, false>>::encode(&original, &mut buf, 0).unwrap();
290 let encoded = buf.freeze();
291
292 let decoded =
293 <Vec<u64> as Encoder<BigEndian, 8, false, false>>::decode(&encoded, 0).unwrap();
294
295 assert_eq!(original, decoded);
296 }
297
298 #[test]
300 fn test_vec_u32_solidity_mode() {
301 let original: Vec<u32> = vec![1, 2, 3, 4, 5];
302 let mut buf = BytesMut::new();
303
304 <Vec<u32> as Encoder<BigEndian, 32, true, false>>::encode(&original, &mut buf, 0).unwrap();
305 let encoded = buf.freeze();
306
307 let decoded =
308 <Vec<u32> as Encoder<BigEndian, 32, true, false>>::decode(&encoded, 0).unwrap();
309
310 assert_eq!(original, decoded);
311 }
312}