1use super::{
6 utils::{padded_big_endian, pull_slice, LinkedBytes},
7 ABIDecodeError, ABIVariable,
8};
9
10pub(super) type Bytes = Vec<u8>;
11
12use cfx_types::U256;
13use std::convert::TryInto;
14
15impl ABIVariable for Bytes {
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 byte array",
26 )?);
27 let data_without_length = pointer.as_slice();
28 if U256::from(data_without_length.len()) < expected_length {
29 Err(ABIDecodeError("Invalid length in byte array"))
30 } else {
31 let length = expected_length.as_usize();
32 Ok(data_without_length[0..length].to_vec())
33 }
34 }
35
36 fn to_abi(&self) -> LinkedBytes {
37 let mut result = padded_big_endian(self.len());
38 result.extend_from_slice(self);
39 result.extend_from_slice(&vec![0u8; 31 - (self.len() + 31) % 32]);
40 LinkedBytes::from_bytes(result)
41 }
42
43 fn to_packed_abi(&self) -> LinkedBytes {
44 LinkedBytes::from_bytes(self.clone())
45 }
46}
47
48impl<const N: usize> ABIVariable for [u8; N]
49where [u8; N]: SolidityBytes
50{
51 const BASIC_TYPE: bool = true;
52 const STATIC_LENGTH: Option<usize> = Some(32);
55
56 fn from_abi(data: &[u8]) -> Result<Self, ABIDecodeError> {
57 let pointer = &mut data.iter();
58
59 let data_without_length = pointer.as_slice();
60 if data_without_length.len() < N {
61 Err(ABIDecodeError("Invalid length in byte array"))
62 } else {
63 Ok(data_without_length[0..N]
64 .try_into()
65 .expect("Length must correct"))
66 }
67 }
68
69 fn to_abi(&self) -> LinkedBytes {
70 let mut result = vec![0u8; 32];
71 result[0..N].copy_from_slice(self);
72 LinkedBytes::from_bytes(result)
73 }
74
75 fn to_packed_abi(&self) -> LinkedBytes {
76 LinkedBytes::from_bytes(self.to_vec())
77 }
78}
79
80pub trait SolidityBytes {}
81
82macro_rules! mark_solidity_bytes {
83 ($($idx:tt),*) => {
84 $(impl SolidityBytes for [u8;$idx] {})*
85 }
86}
87mark_solidity_bytes!(
88 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
89 23, 24, 25, 26, 27, 28, 29, 30, 31, 32
90);