chore(core): convenience impls for Bytes (#1421)

* chore(core): convenience impls for Bytes

* update asserts
This commit is contained in:
Matthias Seitz 2022-06-28 18:30:59 +02:00 committed by GitHub
parent f17f900d01
commit 7c6462be02
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 91 additions and 11 deletions

View File

@ -189,18 +189,18 @@ fn can_gen_human_readable_with_structs() {
let call = BarCall { x: 1u64.into(), y: 0u64.into(), addr: Address::random() };
let encoded_call = contract.encode("bar", (call.x, call.y, call.addr)).unwrap();
assert_eq!(encoded_call, call.clone().encode().into());
assert_eq!(encoded_call, call.clone().encode());
let decoded_call = BarCall::decode(encoded_call.as_ref()).unwrap();
assert_eq!(call, decoded_call);
let contract_call = SimpleContractCalls::Bar(call);
let decoded_enum = SimpleContractCalls::decode(encoded_call.as_ref()).unwrap();
assert_eq!(contract_call, decoded_enum);
assert_eq!(encoded_call, contract_call.encode().into());
assert_eq!(encoded_call, contract_call.encode());
let call = YeetCall(1u64.into(), 0u64.into(), Address::zero());
let encoded_call = contract.encode("yeet", (call.0, call.1, call.2)).unwrap();
assert_eq!(encoded_call, call.clone().encode().into());
assert_eq!(encoded_call, call.clone().encode());
let decoded_call = YeetCall::decode(encoded_call.as_ref()).unwrap();
assert_eq!(call, decoded_call);
@ -208,7 +208,7 @@ fn can_gen_human_readable_with_structs() {
let decoded_enum = SimpleContractCalls::decode(encoded_call.as_ref()).unwrap();
assert_eq!(contract_call, decoded_enum);
assert_eq!(contract_call, call.into());
assert_eq!(encoded_call, contract_call.encode().into());
assert_eq!(encoded_call, contract_call.encode());
}
#[test]
@ -235,26 +235,26 @@ fn can_handle_overloaded_functions() {
let call = GetValueCall;
let encoded_call = contract.encode("getValue", ()).unwrap();
assert_eq!(encoded_call, call.clone().encode().into());
assert_eq!(encoded_call, call.clone().encode());
let decoded_call = GetValueCall::decode(encoded_call.as_ref()).unwrap();
assert_eq!(call, decoded_call);
let contract_call = SimpleContractCalls::GetValue(call);
let decoded_enum = SimpleContractCalls::decode(encoded_call.as_ref()).unwrap();
assert_eq!(contract_call, decoded_enum);
assert_eq!(encoded_call, contract_call.encode().into());
assert_eq!(encoded_call, contract_call.encode());
let call = GetValueWithOtherValueCall { other_value: 420u64.into() };
let encoded_call = contract.encode_with_selector([15, 244, 201, 22], call.other_value).unwrap();
assert_eq!(encoded_call, call.clone().encode().into());
assert_eq!(encoded_call, call.clone().encode());
let decoded_call = GetValueWithOtherValueCall::decode(encoded_call.as_ref()).unwrap();
assert_eq!(call, decoded_call);
let contract_call = SimpleContractCalls::GetValueWithOtherValue(call);
let decoded_enum = SimpleContractCalls::decode(encoded_call.as_ref()).unwrap();
assert_eq!(contract_call, decoded_enum);
assert_eq!(encoded_call, contract_call.encode().into());
assert_eq!(encoded_call, contract_call.encode());
let call =
GetValueWithOtherValueAndAddrCall { other_value: 420u64.into(), addr: Address::random() };
@ -267,7 +267,7 @@ fn can_handle_overloaded_functions() {
let contract_call = SimpleContractCalls::GetValueWithOtherValueAndAddr(call);
let decoded_enum = SimpleContractCalls::decode(encoded_call.as_ref()).unwrap();
assert_eq!(contract_call, decoded_enum);
assert_eq!(encoded_call, contract_call.encode().into());
assert_eq!(encoded_call, contract_call.encode());
let call = SetValue0Call("message".to_string());
let _contract_call = SimpleContractCalls::SetValue0(call);
@ -443,7 +443,7 @@ fn can_generate_nested_types() {
let call = MyfunCall { a: a.clone() };
let encoded_call = contract.encode("myfun", (a,)).unwrap();
assert_eq!(encoded_call, call.clone().encode().into());
assert_eq!(encoded_call, call.clone().encode());
let decoded_call = MyfunCall::decode(encoded_call.as_ref()).unwrap();
assert_eq!(call, decoded_call);
}

View File

@ -57,6 +57,7 @@ macro_rules! impl_abi_codec {
impl_abi_codec!(
Vec<u8>,
Bytes,
bytes::Bytes,
Address,
bool,
String,

View File

@ -125,6 +125,7 @@ macro_rules! impl_abi_type {
impl_abi_type!(
Bytes => Bytes,
bytes::Bytes => Bytes,
Vec<u8> => Array(Box::new(ParamType::Uint(8))),
Address => Address,
bool => Bool,

View File

@ -159,6 +159,19 @@ impl Tokenizable for Bytes {
}
}
impl Tokenizable for bytes::Bytes {
fn from_token(token: Token) -> Result<Self, InvalidOutputType> {
match token {
Token::Bytes(s) => Ok(s.into()),
other => Err(InvalidOutputType(format!("Expected `Bytes`, got {:?}", other))),
}
}
fn into_token(self) -> Token {
Token::Bytes(self.to_vec())
}
}
impl Tokenizable for H256 {
fn from_token(token: Token) -> Result<Self, InvalidOutputType> {
match token {
@ -287,7 +300,7 @@ macro_rules! tokenizable_item {
tokenizable_item! {
Token, String, Address, H256, U256, I256, U128, bool, Vec<u8>,
i8, i16, i32, i64, i128, u16, u32, u64, u128, Bytes,
i8, i16, i32, i64, i128, u16, u32, u64, u128, Bytes, bytes::Bytes,
}
macro_rules! impl_tokenizable_item_tuple {

View File

@ -2,8 +2,10 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
use thiserror::Error;
use std::{
borrow::Borrow,
clone::Clone,
fmt::{Debug, Display, Formatter, LowerHex, Result as FmtResult},
ops::Deref,
str::FromStr,
};
@ -36,12 +38,45 @@ impl Bytes {
}
}
impl Deref for Bytes {
type Target = [u8];
#[inline]
fn deref(&self) -> &[u8] {
self.as_ref()
}
}
impl AsRef<[u8]> for Bytes {
fn as_ref(&self) -> &[u8] {
self.0.as_ref()
}
}
impl Borrow<[u8]> for Bytes {
fn borrow(&self) -> &[u8] {
self.as_ref()
}
}
impl IntoIterator for Bytes {
type Item = u8;
type IntoIter = bytes::buf::IntoIter<bytes::Bytes>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl<'a> IntoIterator for &'a Bytes {
type Item = &'a u8;
type IntoIter = core::slice::Iter<'a, u8>;
fn into_iter(self) -> Self::IntoIter {
self.as_ref().iter()
}
}
impl From<bytes::Bytes> for Bytes {
fn from(src: bytes::Bytes) -> Self {
Self(src)
@ -66,6 +101,36 @@ impl<'a, const N: usize> From<&'a [u8; N]> for Bytes {
}
}
impl PartialEq<[u8]> for Bytes {
fn eq(&self, other: &[u8]) -> bool {
self.as_ref() == other
}
}
impl PartialEq<Bytes> for [u8] {
fn eq(&self, other: &Bytes) -> bool {
*other == *self
}
}
impl PartialEq<Vec<u8>> for Bytes {
fn eq(&self, other: &Vec<u8>) -> bool {
self.as_ref() == &other[..]
}
}
impl PartialEq<Bytes> for Vec<u8> {
fn eq(&self, other: &Bytes) -> bool {
*other == *self
}
}
impl PartialEq<bytes::Bytes> for Bytes {
fn eq(&self, other: &bytes::Bytes) -> bool {
other == self.as_ref()
}
}
#[derive(Debug, Clone, Error)]
#[error("Failed to parse bytes: {0}")]
pub struct ParseBytesError(String);