1use super::{
6 utils::{
7 padded_big_endian, pull_slice, read_abi_list, ABIListWriter,
8 LinkedBytes,
9 },
10 ABIDecodeError, ABIVariable,
11};
12use cfx_types::U256;
13use std::{convert::TryFrom, fmt::Debug};
14
15impl<T: ABIVariable> ABIVariable for Vec<T> {
16 const BASIC_TYPE: bool = false;
17 const STATIC_LENGTH: Option<usize> = None;
18
19 fn from_abi(data: &[u8]) -> Result<Self, ABIDecodeError> {
20 let pointer = &mut data.iter();
21
22 let expected_length = U256::from_big_endian(pull_slice(
23 pointer,
24 32,
25 "Incomplete length for dynamic input parameter",
26 )?);
27 let data_without_length = pointer.as_slice();
28 let mut i = U256::zero();
29 let mut results = Vec::new();
30 while i < expected_length {
31 results.push(read_abi_list::<T>(data_without_length, pointer)?);
32 i = i + 1;
33 }
34 Ok(results)
35 }
36
37 fn to_abi(&self) -> LinkedBytes {
38 let length = LinkedBytes::from_bytes(padded_big_endian(self.len()));
39 let mut recorder = ABIListWriter::with_heads_length(
40 T::STATIC_LENGTH.unwrap_or(32) * self.len(),
41 );
42
43 for item in self {
44 recorder.write_down(item);
45 }
46 let mut answer = length;
47 answer.append(&mut recorder.into_linked_bytes());
48 answer
49 }
50
51 fn to_packed_abi(&self) -> LinkedBytes {
52 let mut record = LinkedBytes::new();
53
54 for item in self {
55 record.append(&mut item.to_packed_abi())
56 }
57 record
58 }
59}
60
61impl<T: ABIVariable + Debug, const N: usize> ABIVariable for [T; N] {
62 const BASIC_TYPE: bool = false;
63 const STATIC_LENGTH: Option<usize> = if let Some(length) = T::STATIC_LENGTH
64 {
65 Some(length * N)
66 } else {
67 None
68 };
69
70 fn from_abi(data: &[u8]) -> Result<Self, ABIDecodeError> {
71 let pointer = &mut data.iter();
72
73 let data_without_length = pointer.as_slice();
74 let mut results = Vec::new();
75 for _ in 0..N {
76 results.push(read_abi_list::<T>(data_without_length, pointer)?);
77 }
78 let results =
79 <[T; N]>::try_from(results).expect("Vector length must correct");
80 Ok(results)
81 }
82
83 fn to_abi(&self) -> LinkedBytes {
84 let mut recorder = ABIListWriter::with_heads_length(
85 T::STATIC_LENGTH.unwrap_or(32) * N,
86 );
87
88 for item in self {
89 recorder.write_down(item);
90 }
91 recorder.into_linked_bytes()
92 }
93
94 fn to_packed_abi(&self) -> LinkedBytes {
95 let mut record = LinkedBytes::new();
96
97 for item in self {
98 record.append(&mut item.to_packed_abi())
99 }
100 record
101 }
102}