use super::utils::*;
use super::Parameter;
use ethane_types::{Address, H256, U128, U256, U64};
use std::convert::From;
impl Parameter {
#[inline]
pub fn new_int(bytes: [u8; 32], signed: bool) -> Self {
if signed {
Self::Int(H256::from(&bytes), 256)
} else {
Self::Uint(H256::from(&bytes), 256)
}
}
#[inline]
pub fn new_fixed_bytes(bytes: &[u8]) -> Self {
Self::FixedBytes(bytes.to_vec())
}
#[inline]
pub fn new_bytes(bytes: &[u8]) -> Self {
Self::Bytes(bytes.to_vec())
}
}
impl From<u8> for Parameter {
#[inline]
fn from(input: u8) -> Self {
Self::Uint(H256::from_int_unchecked(input), 8)
}
}
impl From<u16> for Parameter {
#[inline]
fn from(input: u16) -> Self {
Self::Uint(H256::from_int_unchecked(input), 16)
}
}
impl From<u32> for Parameter {
#[inline]
fn from(input: u32) -> Self {
Self::Uint(H256::from_int_unchecked(input), 32)
}
}
impl From<u64> for Parameter {
#[inline]
fn from(input: u64) -> Self {
Self::Uint(H256::from_int_unchecked(input), 64)
}
}
impl From<u128> for Parameter {
#[inline]
fn from(input: u128) -> Self {
Self::Uint(H256::from_int_unchecked(input), 128)
}
}
impl From<i8> for Parameter {
#[inline]
fn from(input: i8) -> Self {
Self::Int(H256::from_int_unchecked(input), 8)
}
}
impl From<i16> for Parameter {
#[inline]
fn from(input: i16) -> Self {
Self::Int(H256::from_int_unchecked(input), 16)
}
}
impl From<i32> for Parameter {
#[inline]
fn from(input: i32) -> Self {
Self::Int(H256::from_int_unchecked(input), 32)
}
}
impl From<i64> for Parameter {
#[inline]
fn from(input: i64) -> Self {
Self::Int(H256::from_int_unchecked(input), 64)
}
}
impl From<i128> for Parameter {
#[inline]
fn from(input: i128) -> Self {
Self::Int(H256::from_int_unchecked(input), 128)
}
}
impl From<bool> for Parameter {
#[inline]
fn from(input: bool) -> Self {
Self::Bool(H256::from_int_unchecked(u8::from(input)))
}
}
impl From<&str> for Parameter {
#[inline]
fn from(input: &str) -> Self {
Self::String(input.as_bytes().to_vec())
}
}
impl From<Address> for Parameter {
#[inline]
fn from(input: Address) -> Self {
Self::Address(H256::from(&left_pad_to_32_bytes(input.as_bytes())))
}
}
impl From<U64> for Parameter {
#[inline]
fn from(input: U64) -> Self {
Self::Uint(H256::from(&left_pad_to_32_bytes(input.as_bytes())), 64)
}
}
impl From<U128> for Parameter {
#[inline]
fn from(input: U128) -> Self {
Self::Uint(H256::from(&left_pad_to_32_bytes(input.as_bytes())), 128)
}
}
impl From<U256> for Parameter {
#[inline]
fn from(input: U256) -> Self {
Self::Uint(H256::from(input.into_bytes()), 256)
}
}
#[cfg(test)]
mod test {
use super::*;
use hex_literal::hex;
use std::convert::TryFrom;
#[test]
fn parameter_from_elementary_numeric_type() {
let param = Parameter::from(17u8);
if let Parameter::Uint(value, len) = param {
let mut expected = [0u8; 32];
expected[31] = 17;
assert_eq!(len, 8);
assert_eq!(value, H256::from(expected));
} else {
panic!("From u8 test failed")
}
let param = Parameter::from(0b1110_0100_0000_0010_u16);
if let Parameter::Uint(value, len) = param {
let mut expected = [0u8; 32];
expected[30..].copy_from_slice(&[228, 2]);
assert_eq!(len, 16);
assert_eq!(value, H256::from(expected));
} else {
panic!("From u16 test failed")
}
let param = Parameter::from(0b1110_0100_0000_0010_u32);
if let Parameter::Uint(value, len) = param {
let mut expected = [0u8; 32];
expected[30..].copy_from_slice(&[228, 2]);
assert_eq!(len, 32);
assert_eq!(value, H256::from(expected));
} else {
panic!("From u16 test failed")
}
let param = Parameter::from(0b1110_0100_0000_0010_0000_0000_u64);
if let Parameter::Uint(value, len) = param {
let mut expected = [0u8; 32];
expected[29..].copy_from_slice(&[228, 2, 0]);
assert_eq!(len, 64);
assert_eq!(value, H256::from(expected));
} else {
panic!("From u16 test failed")
}
let param = Parameter::from(276479423123262501563991868538311671808u128);
if let Parameter::Uint(value, len) = param {
let mut expected = [0u8; 32];
expected[16] = 208;
assert_eq!(len, 128);
assert_eq!(value, H256::from(expected));
} else {
panic!("From u128 test failed")
}
let param = Parameter::from(-123i8);
if let Parameter::Int(value, len) = param {
let mut expected = [0u8; 32];
expected[31] = 133;
assert_eq!(len, 8);
assert_eq!(value, H256::from(expected));
} else {
panic!("From i8 test failed")
}
let param = Parameter::from(-123i16);
if let Parameter::Int(value, len) = param {
let expected = hex!("000000000000000000000000000000000000000000000000000000000000ff85");
assert_eq!(len, 16);
assert_eq!(value, H256::from(expected));
} else {
panic!("From i16 test failed")
}
let param = Parameter::from(-123i32);
if let Parameter::Int(value, len) = param {
let expected = hex!("00000000000000000000000000000000000000000000000000000000ffffff85");
assert_eq!(len, 32);
assert_eq!(value, H256::from(expected));
} else {
panic!("From i32 test failed")
}
let param = Parameter::from(-12345678987654321_i64);
if let Parameter::Int(value, len) = param {
let expected = hex!("000000000000000000000000000000000000000000000000ffd423ab9d6e0b4f");
assert_eq!(len, 64);
assert_eq!(value, H256::from(expected));
} else {
panic!("From i64 test failed")
}
let param = Parameter::from(-12345678987654321_i128);
if let Parameter::Int(value, len) = param {
let expected = hex!("00000000000000000000000000000000ffffffffffffffffffd423ab9d6e0b4f");
assert_eq!(len, 128);
assert_eq!(value, H256::from(expected));
} else {
panic!("From i128 test failed")
}
let param = Parameter::from(true);
if let Parameter::Bool(value) = param {
let mut expected = [0u8; 32];
expected[31] = 1;
assert_eq!(value, H256::from(expected));
} else {
panic!("From bool test failed")
}
}
#[test]
fn parameter_from_ethereum_types() {
let param = Parameter::from(U64::zero());
if let Parameter::Uint(value, len) = param {
assert_eq!(len, 64);
assert_eq!(value.into_bytes(), [0u8; 32]);
} else {
panic!("From U64 test failed")
}
let param = Parameter::from(U128::try_from("12345").unwrap());
if let Parameter::Uint(value, len) = param {
let mut expected = [0u8; 32];
expected[28..].copy_from_slice(&0x12345u32.to_be_bytes());
assert_eq!(len, 128);
assert_eq!(value.into_bytes(), expected);
} else {
panic!("From U128 test failed")
}
let param = Parameter::from(U256::try_from("123456789").unwrap());
if let Parameter::Uint(value, len) = param {
let mut expected = [0u8; 32];
expected[24..].copy_from_slice(&0x123456789u64.to_be_bytes());
assert_eq!(len, 256);
assert_eq!(value.into_bytes(), expected);
} else {
panic!("From U256 test failed")
}
let param = Parameter::from(
Address::try_from("0x95eDA452256C1190947f9ba1fD19422f0120858a").unwrap(),
);
if let Parameter::Address(value) = param {
let expected = hex!("00000000000000000000000095eDA452256C1190947f9ba1fD19422f0120858a");
assert_eq!(value.into_bytes(), expected);
} else {
panic!("From U256 test failed")
}
}
#[test]
#[rustfmt::skip]
fn parameter_from_dynamic_types() {
let param = Parameter::from("Hello, world!");
if let Parameter::String(value) = param {
let expected = hex!("48656c6c6f2c20776f726c6421");
assert_eq!(value, expected);
} else {
panic!("From &str test failed")
}
let bytes = [1u8; 43];
let param = Parameter::new_bytes(&bytes[..]);
if let Parameter::Bytes(value) = param {
let expected = hex!(
"01010101010101010101010101010101
01010101010101010101010101010101
0101010101010101010101");
assert_eq!(value, expected);
} else {
panic!("From &[u8] test failed")
}
let bytes = [1u8; 43];
let param = Parameter::new_fixed_bytes(&bytes[..]);
if let Parameter::FixedBytes(value) = param {
let expected = hex!(
"01010101010101010101010101010101
01010101010101010101010101010101
0101010101010101010101");
assert_eq!(value, expected);
} else {
panic!("From &[u8] test failed")
}
}
#[test]
fn parameter_from_fixed_bytes() {
let param = Parameter::new_int([14; 32], true); if let Parameter::Int(value, len) = param {
assert_eq!(len, 256);
assert_eq!(value.into_bytes(), [14u8; 32]);
} else {
panic!("Signed integer from fixed slice test failed");
}
let param = Parameter::new_int([12; 32], false); if let Parameter::Uint(value, len) = param {
assert_eq!(len, 256);
assert_eq!(value.into_bytes(), [12u8; 32]);
} else {
panic!("Unsigned integer from fixed slice test failed");
}
}
}