ethane_abi/parameter/
construction.rs

1use super::utils::*;
2use super::Parameter;
3use ethane_types::{Address, H256, U128, U256, U64};
4
5use std::convert::From;
6
7impl Parameter {
8    #[inline]
9    pub fn new_int(bytes: [u8; 32], signed: bool) -> Self {
10        if signed {
11            Self::Int(H256::from(&bytes), 256)
12        } else {
13            Self::Uint(H256::from(&bytes), 256)
14        }
15    }
16
17    /// Creates a new [`FixedBytes`](Parameter::FixedBytes) parameter.
18    #[inline]
19    pub fn new_fixed_bytes(bytes: &[u8]) -> Self {
20        Self::FixedBytes(bytes.to_vec())
21    }
22
23    /// Creates a new [`Bytes`](Parameter::Bytes) parameter.
24    #[inline]
25    pub fn new_bytes(bytes: &[u8]) -> Self {
26        Self::Bytes(bytes.to_vec())
27    }
28}
29
30// Unsigned elementary integer types
31impl From<u8> for Parameter {
32    #[inline]
33    fn from(input: u8) -> Self {
34        Self::Uint(H256::from_int_unchecked(input), 8)
35    }
36}
37
38impl From<u16> for Parameter {
39    #[inline]
40    fn from(input: u16) -> Self {
41        Self::Uint(H256::from_int_unchecked(input), 16)
42    }
43}
44
45impl From<u32> for Parameter {
46    #[inline]
47    fn from(input: u32) -> Self {
48        Self::Uint(H256::from_int_unchecked(input), 32)
49    }
50}
51
52impl From<u64> for Parameter {
53    #[inline]
54    fn from(input: u64) -> Self {
55        Self::Uint(H256::from_int_unchecked(input), 64)
56    }
57}
58
59impl From<u128> for Parameter {
60    #[inline]
61    fn from(input: u128) -> Self {
62        Self::Uint(H256::from_int_unchecked(input), 128)
63    }
64}
65
66// Signed elementary integer types
67impl From<i8> for Parameter {
68    #[inline]
69    fn from(input: i8) -> Self {
70        Self::Int(H256::from_int_unchecked(input), 8)
71    }
72}
73
74impl From<i16> for Parameter {
75    #[inline]
76    fn from(input: i16) -> Self {
77        Self::Int(H256::from_int_unchecked(input), 16)
78    }
79}
80
81impl From<i32> for Parameter {
82    #[inline]
83    fn from(input: i32) -> Self {
84        Self::Int(H256::from_int_unchecked(input), 32)
85    }
86}
87
88impl From<i64> for Parameter {
89    #[inline]
90    fn from(input: i64) -> Self {
91        Self::Int(H256::from_int_unchecked(input), 64)
92    }
93}
94
95impl From<i128> for Parameter {
96    #[inline]
97    fn from(input: i128) -> Self {
98        Self::Int(H256::from_int_unchecked(input), 128)
99    }
100}
101
102// Boolean type
103impl From<bool> for Parameter {
104    #[inline]
105    fn from(input: bool) -> Self {
106        Self::Bool(H256::from_int_unchecked(u8::from(input)))
107    }
108}
109
110// String literal into a dynamic array of bytes
111impl From<&str> for Parameter {
112    #[inline]
113    fn from(input: &str) -> Self {
114        Self::String(input.as_bytes().to_vec())
115    }
116}
117
118// From Ethereum types
119impl From<Address> for Parameter {
120    #[inline]
121    fn from(input: Address) -> Self {
122        Self::Address(H256::from(&left_pad_to_32_bytes(input.as_bytes())))
123    }
124}
125
126impl From<U64> for Parameter {
127    #[inline]
128    fn from(input: U64) -> Self {
129        Self::Uint(H256::from(&left_pad_to_32_bytes(input.as_bytes())), 64)
130    }
131}
132
133impl From<U128> for Parameter {
134    #[inline]
135    fn from(input: U128) -> Self {
136        Self::Uint(H256::from(&left_pad_to_32_bytes(input.as_bytes())), 128)
137    }
138}
139
140impl From<U256> for Parameter {
141    #[inline]
142    fn from(input: U256) -> Self {
143        Self::Uint(H256::from(input.into_bytes()), 256)
144    }
145}
146
147#[cfg(test)]
148mod test {
149    use super::*;
150    use hex_literal::hex;
151    use std::convert::TryFrom;
152
153    #[test]
154    fn parameter_from_elementary_numeric_type() {
155        // from u8
156        let param = Parameter::from(17u8);
157        if let Parameter::Uint(value, len) = param {
158            let mut expected = [0u8; 32];
159            expected[31] = 17;
160            assert_eq!(len, 8);
161            assert_eq!(value, H256::from(expected));
162        } else {
163            panic!("From u8 test failed")
164        }
165
166        // from u16
167        let param = Parameter::from(0b1110_0100_0000_0010_u16);
168        if let Parameter::Uint(value, len) = param {
169            let mut expected = [0u8; 32];
170            expected[30..].copy_from_slice(&[228, 2]);
171            assert_eq!(len, 16);
172            assert_eq!(value, H256::from(expected));
173        } else {
174            panic!("From u16 test failed")
175        }
176
177        // from u32
178        let param = Parameter::from(0b1110_0100_0000_0010_u32);
179        if let Parameter::Uint(value, len) = param {
180            let mut expected = [0u8; 32];
181            expected[30..].copy_from_slice(&[228, 2]);
182            assert_eq!(len, 32);
183            assert_eq!(value, H256::from(expected));
184        } else {
185            panic!("From u16 test failed")
186        }
187
188        // from u64
189        let param = Parameter::from(0b1110_0100_0000_0010_0000_0000_u64);
190        if let Parameter::Uint(value, len) = param {
191            let mut expected = [0u8; 32];
192            expected[29..].copy_from_slice(&[228, 2, 0]);
193            assert_eq!(len, 64);
194            assert_eq!(value, H256::from(expected));
195        } else {
196            panic!("From u16 test failed")
197        }
198
199        // from u128
200        // this value starts with 1101_0000 ... then a lot of zeros
201        let param = Parameter::from(276479423123262501563991868538311671808u128);
202        if let Parameter::Uint(value, len) = param {
203            let mut expected = [0u8; 32];
204            expected[16] = 208;
205            assert_eq!(len, 128);
206            assert_eq!(value, H256::from(expected));
207        } else {
208            panic!("From u128 test failed")
209        }
210
211        // from i8
212        let param = Parameter::from(-123i8);
213        if let Parameter::Int(value, len) = param {
214            let mut expected = [0u8; 32];
215            expected[31] = 133;
216            assert_eq!(len, 8);
217            assert_eq!(value, H256::from(expected));
218        } else {
219            panic!("From i8 test failed")
220        }
221
222        // from i16
223        let param = Parameter::from(-123i16);
224        if let Parameter::Int(value, len) = param {
225            let expected = hex!("000000000000000000000000000000000000000000000000000000000000ff85");
226            assert_eq!(len, 16);
227            assert_eq!(value, H256::from(expected));
228        } else {
229            panic!("From i16 test failed")
230        }
231
232        // from i16
233        let param = Parameter::from(-123i32);
234        if let Parameter::Int(value, len) = param {
235            let expected = hex!("00000000000000000000000000000000000000000000000000000000ffffff85");
236            assert_eq!(len, 32);
237            assert_eq!(value, H256::from(expected));
238        } else {
239            panic!("From i32 test failed")
240        }
241
242        // from i64
243        let param = Parameter::from(-12345678987654321_i64);
244        if let Parameter::Int(value, len) = param {
245            let expected = hex!("000000000000000000000000000000000000000000000000ffd423ab9d6e0b4f");
246            assert_eq!(len, 64);
247            assert_eq!(value, H256::from(expected));
248        } else {
249            panic!("From i64 test failed")
250        }
251
252        // from i128
253        let param = Parameter::from(-12345678987654321_i128);
254        if let Parameter::Int(value, len) = param {
255            let expected = hex!("00000000000000000000000000000000ffffffffffffffffffd423ab9d6e0b4f");
256            assert_eq!(len, 128);
257            assert_eq!(value, H256::from(expected));
258        } else {
259            panic!("From i128 test failed")
260        }
261
262        // from bool
263        let param = Parameter::from(true);
264        if let Parameter::Bool(value) = param {
265            let mut expected = [0u8; 32];
266            expected[31] = 1;
267            assert_eq!(value, H256::from(expected));
268        } else {
269            panic!("From bool test failed")
270        }
271    }
272
273    #[test]
274    fn parameter_from_ethereum_types() {
275        // from U64
276        let param = Parameter::from(U64::zero());
277        if let Parameter::Uint(value, len) = param {
278            assert_eq!(len, 64);
279            assert_eq!(value.into_bytes(), [0u8; 32]);
280        } else {
281            panic!("From U64 test failed")
282        }
283
284        // from U128
285        let param = Parameter::from(U128::try_from("12345").unwrap());
286        if let Parameter::Uint(value, len) = param {
287            let mut expected = [0u8; 32];
288            expected[28..].copy_from_slice(&0x12345u32.to_be_bytes());
289            assert_eq!(len, 128);
290            assert_eq!(value.into_bytes(), expected);
291        } else {
292            panic!("From U128 test failed")
293        }
294
295        // from U256
296        let param = Parameter::from(U256::try_from("123456789").unwrap());
297        if let Parameter::Uint(value, len) = param {
298            let mut expected = [0u8; 32];
299            expected[24..].copy_from_slice(&0x123456789u64.to_be_bytes());
300            assert_eq!(len, 256);
301            assert_eq!(value.into_bytes(), expected);
302        } else {
303            panic!("From U256 test failed")
304        }
305
306        // from Address
307        let param = Parameter::from(
308            Address::try_from("0x95eDA452256C1190947f9ba1fD19422f0120858a").unwrap(),
309        );
310        if let Parameter::Address(value) = param {
311            let expected = hex!("00000000000000000000000095eDA452256C1190947f9ba1fD19422f0120858a");
312            assert_eq!(value.into_bytes(), expected);
313        } else {
314            panic!("From U256 test failed")
315        }
316    }
317
318    #[test]
319    #[rustfmt::skip]
320    fn parameter_from_dynamic_types() {
321        // From &str string literal
322        let param = Parameter::from("Hello, world!");
323        if let Parameter::String(value) = param {
324            let expected = hex!("48656c6c6f2c20776f726c6421");
325            assert_eq!(value, expected);
326        } else {
327            panic!("From &str test failed")
328        }
329
330        // From byte slice
331        let bytes = [1u8; 43];
332        let param = Parameter::new_bytes(&bytes[..]);
333        if let Parameter::Bytes(value) = param {
334            let expected = hex!(
335            "01010101010101010101010101010101
336                01010101010101010101010101010101
337                0101010101010101010101");
338            assert_eq!(value, expected);
339        } else {
340            panic!("From &[u8] test failed")
341        }
342
343        let bytes = [1u8; 43];
344        let param = Parameter::new_fixed_bytes(&bytes[..]);
345        if let Parameter::FixedBytes(value) = param {
346            let expected = hex!(
347            "01010101010101010101010101010101
348                01010101010101010101010101010101
349                0101010101010101010101");
350            assert_eq!(value, expected);
351        } else {
352            panic!("From &[u8] test failed")
353        }
354    }
355
356    #[test]
357    fn parameter_from_fixed_bytes() {
358        // Signed integer from fixed slice
359        let param = Parameter::new_int([14; 32], true); // signed = true
360        if let Parameter::Int(value, len) = param {
361            assert_eq!(len, 256);
362            assert_eq!(value.into_bytes(), [14u8; 32]);
363        } else {
364            panic!("Signed integer from fixed slice test failed");
365        }
366
367        // Unsigned integer from fixed slice
368        let param = Parameter::new_int([12; 32], false); // signed = false
369        if let Parameter::Uint(value, len) = param {
370            assert_eq!(len, 256);
371            assert_eq!(value.into_bytes(), [12u8; 32]);
372        } else {
373            panic!("Unsigned integer from fixed slice test failed");
374        }
375    }
376}