Skip to content

Commit

Permalink
refactor: distinguish SolType from SolDataType
Browse files Browse the repository at this point in the history
  • Loading branch information
prestwich committed May 2, 2023
1 parent e109f13 commit e9ff977
Show file tree
Hide file tree
Showing 21 changed files with 1,307 additions and 1,103 deletions.
4 changes: 2 additions & 2 deletions abi/sol-type-parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ mod udt;
use udt::*;

enum SolInput {
Type(SolType),
Type(SolDataType),
StructDef(SolStructDef),
ValueTypeDef(Udt),
}

impl Parse for SolInput {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let fork = input.fork();
if let Ok(sol_ty) = fork.parse::<SolType>() {
if let Ok(sol_ty) = fork.parse::<SolDataType>() {
input.advance_to(&fork);
return Ok(SolInput::Type(sol_ty));
}
Expand Down
13 changes: 7 additions & 6 deletions abi/sol-type-parser/src/struct.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::r#type::SolType;
use crate::r#type::SolDataType;
use proc_macro2::TokenStream;
use quote::{quote, quote_spanned, ToTokens};
use std::fmt;
Expand All @@ -12,7 +12,7 @@ use syn::{

#[derive(Debug, Clone)]
pub struct SolStructField {
ty: SolType,
ty: SolDataType,
name: Ident,
}

Expand Down Expand Up @@ -128,7 +128,7 @@ impl SolStructDef {
{
let mut encoded = String::from(#encoded_type);
#(
if let Some(s) = <#props_tys as SolType>::eip712_encode_type() {
if let Some(s) = <#props_tys as SolDataType>::eip712_encode_type() {
encoded.push_str(&s);
}
)*
Expand All @@ -141,11 +141,11 @@ impl SolStructDef {

let encode_data_impl = if self.fields.len() == 1 {
let SolStructField { ty, name } = self.fields.first().unwrap();
quote!(<#ty as SolType>::eip712_data_word(&self.#name).0.to_vec())
quote!(<#ty as SolDataType>::eip712_data_word(&self.#name).0.to_vec())
} else {
quote! {
[#(
<#props_tys as SolType>::eip712_data_word(&self.#props).0,
<#props_tys as SolDataType>::eip712_data_word(&self.#props).0,
)*].concat()
}
};
Expand All @@ -162,12 +162,13 @@ impl SolStructDef {

#[allow(non_snake_case)]
const _: () = {
use ::ethers_abi_enc::{SolType, keccak256, no_std_prelude::*};
use ::ethers_abi_enc::{SolDataType, keccak256, no_std_prelude::*};

#convert

impl ::ethers_abi_enc::SolStruct for #name {
type Tuple = UnderlyingSolTuple;
type Token = <UnderlyingSolTuple as ethers_abi_enc::SolType>::TokenType;

const NAME: &'static str = stringify!(#name);

Expand Down
64 changes: 33 additions & 31 deletions abi/sol-type-parser/src/type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ impl Parse for ArraySize {
pub struct SolTuple {
_tup: Option<kw::tuple>,
parenthesized: syn::token::Paren,
inner: Punctuated<SolType, Token![,]>,
inner: Punctuated<SolDataType, Token![,]>,
}

impl fmt::Debug for SolTuple {
Expand Down Expand Up @@ -83,7 +83,7 @@ impl Parse for SolTuple {
Ok(SolTuple {
_tup: input.parse()?,
parenthesized: parenthesized!(content in input),
inner: content.parse_terminated(SolType::parse, Token![,])?,
inner: content.parse_terminated(SolDataType::parse, Token![,])?,
})
}
}
Expand All @@ -97,9 +97,9 @@ impl ToTokens for SolTuple {
}

#[derive(Clone)]
pub enum SolType {
pub enum SolDataType {
Address,
Array(Box<SolType>, ArraySize),
Array(Box<SolDataType>, ArraySize),
Bool,
Bytes,
FixedBytes(LitInt),
Expand All @@ -110,7 +110,7 @@ pub enum SolType {
Other(Ident),
}

impl fmt::Debug for SolType {
impl fmt::Debug for SolDataType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Address => write!(f, "Address"),
Expand All @@ -130,11 +130,11 @@ impl fmt::Debug for SolType {
}
}

impl fmt::Display for SolType {
impl fmt::Display for SolDataType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SolType::Address => write!(f, "address"),
SolType::Array(ty, size) => {
SolDataType::Address => write!(f, "address"),
SolDataType::Array(ty, size) => {
write!(
f,
"{}[{}]",
Expand All @@ -145,47 +145,49 @@ impl fmt::Display for SolType {
.unwrap_or_default()
)
}
SolType::Bool => write!(f, "bool"),
SolType::Bytes => write!(f, "bytes"),
SolType::FixedBytes(size) => write!(f, "bytes{}", size.base10_digits()),
SolType::Int(size) => write!(f, "int{}", size.base10_digits()),
SolType::String => write!(f, "string"),
SolType::Uint(size) => write!(f, "uint{}", size.base10_digits()),
SolType::Tuple(inner) => write!(f, "{}", inner),
SolType::Other(name) => write!(f, "{}", name),
SolDataType::Bool => write!(f, "bool"),
SolDataType::Bytes => write!(f, "bytes"),
SolDataType::FixedBytes(size) => write!(f, "bytes{}", size.base10_digits()),
SolDataType::Int(size) => write!(f, "int{}", size.base10_digits()),
SolDataType::String => write!(f, "string"),
SolDataType::Uint(size) => write!(f, "uint{}", size.base10_digits()),
SolDataType::Tuple(inner) => write!(f, "{}", inner),
SolDataType::Other(name) => write!(f, "{}", name),
}
}
}

impl ToTokens for SolType {
impl ToTokens for SolDataType {
fn to_tokens(&self, tokens: &mut TokenStream) {
let expanded = match self {
SolType::Address => quote! { ::ethers_abi_enc::sol_type::Address },
SolType::Array(inner, size) => {
SolDataType::Address => quote! { ::ethers_abi_enc::sol_data::Address },
SolDataType::Array(inner, size) => {
if let Some(size) = &size.size {
quote! {
::ethers_abi_enc::sol_type::FixedArray<#inner, #size>
::ethers_abi_enc::sol_data::FixedArray<#inner, #size>
}
} else {
quote! {
::ethers_abi_enc::sol_type::Array<#inner>
::ethers_abi_enc::sol_data::Array<#inner>
}
}
}
SolType::Bool => quote! { ::ethers_abi_enc::sol_type::Bool },
SolType::Bytes => quote! { ::ethers_abi_enc::sol_type::Bytes },
SolType::FixedBytes(size) => quote! {::ethers_abi_enc::sol_type::FixedBytes<#size>},
SolType::Int(size) => quote! { ::ethers_abi_enc::sol_type::Int<#size> },
SolType::String => quote! { ::ethers_abi_enc::sol_type::String },
SolType::Uint(size) => quote! { ::ethers_abi_enc::sol_type::Uint<#size> },
SolType::Tuple(inner) => return inner.to_tokens(tokens),
SolType::Other(ident) => quote! { #ident },
SolDataType::Bool => quote! { ::ethers_abi_enc::sol_data::Bool },
SolDataType::Bytes => quote! { ::ethers_abi_enc::sol_data::Bytes },
SolDataType::FixedBytes(size) => {
quote! {::ethers_abi_enc::sol_data::FixedBytes<#size>}
}
SolDataType::Int(size) => quote! { ::ethers_abi_enc::sol_data::Int<#size> },
SolDataType::String => quote! { ::ethers_abi_enc::sol_data::String },
SolDataType::Uint(size) => quote! { ::ethers_abi_enc::sol_data::Uint<#size> },
SolDataType::Tuple(inner) => return inner.to_tokens(tokens),
SolDataType::Other(ident) => quote! { #ident },
};
tokens.extend(expanded);
}
}

impl Parse for SolType {
impl Parse for SolDataType {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let mut candidate = if input.peek(kw::address) {
let _ = input.parse::<kw::address>()?;
Expand Down Expand Up @@ -247,7 +249,7 @@ impl Parse for SolType {
}
}

impl SolType {
impl SolDataType {
pub fn is_non_primitive(&self) -> bool {
matches!(self, Self::Other(_))
}
Expand Down
4 changes: 2 additions & 2 deletions abi/sol-type-parser/src/udt.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use quote::{quote, ToTokens};
use syn::parse::Parse;

use crate::r#type::SolType;
use crate::r#type::SolDataType;

mod kw {
syn::custom_keyword!(is);
Expand All @@ -12,7 +12,7 @@ pub struct Udt {
_type: syn::Token![type],
name: syn::Ident,
_is: kw::is,
ty: SolType,
ty: SolDataType,
_semi: syn::Token![;],
}

Expand Down
76 changes: 38 additions & 38 deletions abi/src/coder/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,11 +310,11 @@ mod tests {

#[cfg(not(feature = "std"))]
use crate::no_std_prelude::*;
use crate::{sol_type, util::pad_u32, SolType};
use crate::{sol_data, util::pad_u32, SolType};

#[test]
fn decode_static_tuple_of_addresses_and_uints() {
type MyTy = (sol_type::Address, sol_type::Address, sol_type::Uint<256>);
type MyTy = (sol_data::Address, sol_data::Address, sol_data::Uint<256>);

let encoded = hex!(
"
Expand All @@ -333,7 +333,7 @@ mod tests {

#[test]
fn decode_dynamic_tuple() {
type MyTy = (sol_type::String, sol_type::String);
type MyTy = (sol_data::String, sol_data::String);
let encoded = hex!(
"
0000000000000000000000000000000000000000000000000000000000000020
Expand All @@ -357,13 +357,13 @@ mod tests {
#[test]
fn decode_nested_tuple() {
type MyTy = (
sol_type::String,
sol_type::Bool,
sol_type::String,
sol_data::String,
sol_data::Bool,
sol_data::String,
(
sol_type::String,
sol_type::String,
(sol_type::String, sol_type::String),
sol_data::String,
sol_data::String,
(sol_data::String, sol_data::String),
),
);

Expand Down Expand Up @@ -411,10 +411,10 @@ mod tests {
#[test]
fn decode_complex_tuple_of_dynamic_and_static_types() {
type MyTy = (
sol_type::Uint<256>,
sol_type::String,
sol_type::Address,
sol_type::Address,
sol_data::Uint<256>,
sol_data::String,
sol_data::Address,
sol_data::Address,
);

let encoded = hex!(
Expand All @@ -441,11 +441,11 @@ mod tests {
#[test]
fn decode_params_containing_dynamic_tuple() {
type MyTy = (
sol_type::Address,
(sol_type::Bool, sol_type::String, sol_type::String),
sol_type::Address,
sol_type::Address,
sol_type::Bool,
sol_data::Address,
(sol_data::Bool, sol_data::String, sol_data::String),
sol_data::Address,
sol_data::Address,
sol_data::Bool,
);

let encoded = hex!(
Expand Down Expand Up @@ -481,10 +481,10 @@ mod tests {
#[test]
fn decode_params_containing_static_tuple() {
type MyTy = (
sol_type::Address,
(sol_type::Address, sol_type::Bool, sol_type::Bool),
sol_type::Address,
sol_type::Address,
sol_data::Address,
(sol_data::Address, sol_data::Bool, sol_data::Bool),
sol_data::Address,
sol_data::Address,
);

let encoded = hex!(
Expand Down Expand Up @@ -514,11 +514,11 @@ mod tests {
#[test]
fn decode_data_with_size_that_is_not_a_multiple_of_32() {
type MyTy = (
sol_type::Uint<256>,
sol_type::String,
sol_type::String,
sol_type::Uint<256>,
sol_type::Uint<256>,
sol_data::Uint<256>,
sol_data::String,
sol_data::String,
sol_data::Uint<256>,
sol_data::Uint<256>,
);

let data = (
Expand Down Expand Up @@ -553,10 +553,10 @@ mod tests {
#[test]
fn decode_after_fixed_bytes_with_less_than_32_bytes() {
type MyTy = (
sol_type::Address,
sol_type::FixedBytes<32>,
sol_type::FixedBytes<4>,
sol_type::String,
sol_data::Address,
sol_data::FixedBytes<32>,
sol_data::FixedBytes<4>,
sol_data::String,
);

let encoded = hex!(
Expand Down Expand Up @@ -592,14 +592,14 @@ mod tests {
);

assert_eq!(
sol_type::String::decode_single(&encoded, false).unwrap(),
sol_data::String::decode_single(&encoded, false).unwrap(),
"不�".to_string()
);
}

#[test]
fn decode_corrupted_dynamic_array() {
type MyTy = sol_type::Array<sol_type::Uint<32>>;
type MyTy = sol_data::Array<sol_data::Uint<32>>;
// line 1 at 0x00 = 0: tail offset of array
// line 2 at 0x20 = 32: length of array
// line 3 at 0x40 = 64: first word
Expand All @@ -623,15 +623,15 @@ mod tests {
0000000000000000000000000000000000000000000000000000000000054321
"
);
assert!(sol_type::Address::decode_single(&input, false).is_ok());
assert!(sol_type::Address::decode_single(&input, true).is_err());
assert!(<(sol_type::Address, sol_type::Address)>::decode_single(&input, true).is_ok());
assert!(sol_data::Address::decode_single(&input, false).is_ok());
assert!(sol_data::Address::decode_single(&input, true).is_err());
assert!(<(sol_data::Address, sol_data::Address)>::decode_single(&input, true).is_ok());
}

#[test]
fn decode_verify_bytes() {
type MyTy = (sol_type::Address, sol_type::FixedBytes<20>);
type MyTy2 = (sol_type::Address, sol_type::Address);
type MyTy = (sol_data::Address, sol_data::FixedBytes<20>);
type MyTy2 = (sol_data::Address, sol_data::Address);

let input = hex!(
"
Expand Down
Loading

0 comments on commit e9ff977

Please sign in to comment.