1use super::{utils::abi_require, ABIDecodeError, ABIVariable, LinkedBytes};
6use cfx_types::{Address, H256, U256};
7
8impl ABIVariable for Address {
9 const BASIC_TYPE: bool = true;
10 const STATIC_LENGTH: Option<usize> = Some(32);
11
12 fn from_abi(data: &[u8]) -> Result<Self, ABIDecodeError> {
13 abi_require(data.len() == 32, "Invalid call data length")?;
14 Ok(Address::from_slice(&data[12..32]))
15 }
16
17 fn to_abi(&self) -> LinkedBytes {
18 let mut answer = vec![0u8; 12];
19 answer.extend_from_slice(self.as_bytes());
20 LinkedBytes::from_bytes(answer)
21 }
22
23 fn to_packed_abi(&self) -> LinkedBytes {
24 LinkedBytes::from_bytes(self.to_fixed_bytes().into())
25 }
26}
27
28impl ABIVariable for U256 {
29 const BASIC_TYPE: bool = true;
30 const STATIC_LENGTH: Option<usize> = Some(32);
31
32 fn from_abi(data: &[u8]) -> Result<Self, ABIDecodeError> {
33 abi_require(data.len() == 32, "Invalid call data length")?;
34 Ok(U256::from_big_endian(&data))
35 }
36
37 fn to_abi(&self) -> LinkedBytes {
38 let mut answer = vec![0u8; 32];
39 self.to_big_endian(&mut answer);
40 LinkedBytes::from_bytes(answer)
41 }
42
43 fn to_packed_abi(&self) -> LinkedBytes { self.to_abi() }
44}
45
46impl ABIVariable for H256 {
47 const BASIC_TYPE: bool = <[u8; 32]>::BASIC_TYPE;
48 const STATIC_LENGTH: Option<usize> = <[u8; 32]>::STATIC_LENGTH;
49
50 fn from_abi(data: &[u8]) -> Result<Self, ABIDecodeError> {
51 Ok(H256::from(<[u8; 32]>::from_abi(data)?))
52 }
53
54 fn to_abi(&self) -> LinkedBytes { self.0.to_abi() }
55
56 fn to_packed_abi(&self) -> LinkedBytes { self.0.to_packed_abi() }
57}
58
59impl ABIVariable for bool {
60 const BASIC_TYPE: bool = true;
61 const STATIC_LENGTH: Option<usize> = Some(32);
62
63 fn from_abi(data: &[u8]) -> Result<Self, ABIDecodeError> {
64 abi_require(data.len() == 32, "Invalid call data length")?;
65 Ok(data[31] != 0)
66 }
67
68 fn to_abi(&self) -> LinkedBytes {
69 let mut answer = vec![0u8; 32];
70 answer[31] = *self as u8;
71 LinkedBytes::from_bytes(answer)
72 }
73
74 fn to_packed_abi(&self) -> LinkedBytes {
75 LinkedBytes::from_bytes(vec![*self as u8])
76 }
77}
78
79macro_rules! impl_abi_variable_for_primitive {
80 () => {};
81 ($ty: ident) => {impl_abi_variable_for_primitive!($ty,);};
82 ($ty: ident, $($rest: ident),*) => {
83 impl ABIVariable for $ty {
84 const BASIC_TYPE: bool = true;
85 const STATIC_LENGTH: Option<usize> = Some(32);
86
87 fn from_abi(data: &[u8]) -> Result<Self, ABIDecodeError> {
88 const BYTES: usize = ($ty::BITS/8) as usize;
89 abi_require(data.len() == 32, "Invalid call data length")?;
90 let mut bytes = [0u8; BYTES];
91 bytes.copy_from_slice(&data[32 - BYTES..]);
92 Ok($ty::from_be_bytes(bytes))
93 }
94
95 fn to_abi(&self) -> LinkedBytes {
96 const BYTES: usize = ($ty::BITS/8) as usize;
97 let mut answer = vec![0u8; 32];
98 answer[32 - BYTES..].copy_from_slice(&self.to_be_bytes());
99 LinkedBytes::from_bytes(answer)
100 }
101
102 fn to_packed_abi(&self) -> LinkedBytes {
103 LinkedBytes::from_bytes(self.to_be_bytes().to_vec())
104 }
105 }
106
107 impl_abi_variable_for_primitive!($($rest),*);
108 }
109}
110
111impl_abi_variable_for_primitive!(U8, u16, u32, u64, u128);
112
113#[allow(dead_code)]
114#[derive(Copy, Clone, Eq, PartialEq)]
115pub struct U8(u8);
116
117impl U8 {
118 #[allow(dead_code)]
119 const BITS: usize = 8;
120
121 #[allow(dead_code)]
122 fn to_be_bytes(self) -> [u8; 1] { [self.0] }
123
124 #[allow(dead_code)]
125 fn from_be_bytes(input: [u8; 1]) -> Self { U8(input[0]) }
126}
127
128#[cfg(test)]
129mod tests_basic {
130 use super::{U8, *};
131 use crate::ABIVariable;
132
133 #[test]
134 fn test_packed_encoding() {
135 let num = 0xDEADBEEFu32;
136 let packed = num.to_packed_abi().to_vec();
137 let expected = num.to_be_bytes().to_vec();
138 assert_eq!(packed, expected);
139 }
140
141 #[test]
142 fn test_u256_abi_basic() {
143 assert!(U256::BASIC_TYPE);
144 assert_eq!(U256::STATIC_LENGTH, Some(32));
145 }
146
147 #[test]
148 fn test_u256_packed_abi_consistency() {
149 let num = U256::max_value();
150 let abi = num.to_abi();
151 let packed_abi = num.to_packed_abi();
152 assert_eq!(abi.to_vec(), packed_abi.to_vec());
153 }
154
155 #[test]
156 fn test_u256_zero_value() {
157 let zero = U256::zero();
158 let encoded = zero.to_abi().to_vec();
159 assert_eq!(encoded, vec![0u8; 32]);
160 }
161
162 #[test]
163 fn test_h256_type_constants() {
164 assert_eq!(H256::BASIC_TYPE, <[u8; 32]>::BASIC_TYPE);
165 assert_eq!(H256::STATIC_LENGTH, <[u8; 32]>::STATIC_LENGTH);
166 }
167
168 #[test]
169 fn test_h256_from_abi_valid() {
170 let input = [42u8; 32];
171 let h256 = H256::from_abi(&input).unwrap();
172 assert_eq!(h256.0, input);
173 }
174
175 #[test]
176 fn test_h256_to_packed_abi() {
177 let h256 = H256([0xBB; 32]);
178 let packed_bytes = h256.to_packed_abi();
179 assert_eq!(packed_bytes.to_vec(), &[0xBB; 32]);
180 }
181
182 #[test]
183 fn test_u8_bits() {
184 assert_eq!(U8::BITS, 8);
185 }
186
187 #[test]
188 fn test_u8_to_be_bytes() {
189 let val = U8::from_be_bytes([123]);
190 assert_eq!(val.to_be_bytes(), [123]);
191 }
192
193 #[test]
194 fn test_u8_from_be_bytes() {
195 let u = U8::from_be_bytes([255]);
196 assert_eq!(u.to_be_bytes(), [255]);
197 }
198
199 #[test]
200 fn test_u8_eq() {
201 let a = U8::from_be_bytes([100]);
202 let b = U8::from_be_bytes([100]);
203 let c = U8::from_be_bytes([200]);
204 assert!(a == b);
205 assert!(a != c);
206 }
207
208 #[test]
209 fn test_u8_boundaries() {
210 let min = U8::from_be_bytes([0]);
211 let max = U8::from_be_bytes([255]);
212 assert_eq!(min.to_be_bytes(), [0]);
213 assert_eq!(max.to_be_bytes(), [255]);
214 }
215
216 #[test]
217 fn test_u8_byte_order_consistency() {
218 let input = [128];
219 let u = U8::from_be_bytes(input);
220 assert_eq!(u.to_be_bytes(), input);
221 }
222}