Skip to content

Commit

Permalink
fix(abigen): builtin trait derives (#2170)
Browse files Browse the repository at this point in the history
* fix(abigen): builtin trait derives

* refactor: EthDisplay

* feat(derive): improve type detection

* chore: cleanup

* chore: edition 2021

* chore: clippy

* chore: use unreachable
  • Loading branch information
DaniPopes committed Feb 21, 2023
1 parent c21362b commit 3732de8
Show file tree
Hide file tree
Showing 20 changed files with 570 additions and 220 deletions.
2 changes: 1 addition & 1 deletion ethers-contract/Cargo.toml
@@ -1,7 +1,7 @@
[package]
name = "ethers-contract"
version = "1.0.2"
edition = "2018"
edition = "2021"
rust-version = "1.64"
authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
license = "MIT OR Apache-2.0"
Expand Down
16 changes: 9 additions & 7 deletions ethers-contract/ethers-contract-abigen/src/contract/errors.rs
Expand Up @@ -52,16 +52,15 @@ impl Context {
hex::encode(error.selector())
);

let mut extra_derives = self.expand_extra_derives();
if util::can_derive_defaults(&error.inputs) {
extra_derives.extend(quote!(Default));
}
let mut derives = self.expand_extra_derives();
let params = error.inputs.iter().map(|param| &param.kind);
util::derive_builtin_traits(params, &mut derives, true, true);

let ethers_contract = ethers_contract_crate();

Ok(quote! {
#[doc = #doc_str]
#[derive(Clone, Debug, Eq, PartialEq, #ethers_contract::EthError, #ethers_contract::EthDisplay, #extra_derives)]
#[derive(Clone, #ethers_contract::EthError, #ethers_contract::EthDisplay, #derives)]
#[etherror(name = #error_name, abi = #abi_signature)]
pub #data_type_definition
})
Expand Down Expand Up @@ -92,14 +91,17 @@ impl Context {
})
.collect::<Vec<_>>();

let extra_derives = self.expand_extra_derives();
let mut derives = self.expand_extra_derives();
let params =
self.abi.errors.values().flatten().flat_map(|err| &err.inputs).map(|param| &param.kind);
util::derive_builtin_traits(params, &mut derives, false, true);

let ethers_core = ethers_core_crate();
let ethers_contract = ethers_contract_crate();

quote! {
#[doc = "Container type for all of the contract's custom errors"]
#[derive(Debug, Clone, PartialEq, Eq, #ethers_contract::EthAbiType, #extra_derives)]
#[derive(Clone, #ethers_contract::EthAbiType, #derives)]
pub enum #enum_name {
#( #variants(#variants), )*
}
Expand Down
21 changes: 12 additions & 9 deletions ethers-contract/ethers-contract-abigen/src/contract/events.rs
Expand Up @@ -62,15 +62,19 @@ impl Context {
})
.collect::<Vec<_>>();

let enum_name = self.expand_event_enum_name();

let mut derives = self.expand_extra_derives();
let params =
self.abi.events.values().flatten().flat_map(|err| &err.inputs).map(|param| &param.kind);
util::derive_builtin_traits(params, &mut derives, false, true);

let ethers_core = ethers_core_crate();
let ethers_contract = ethers_contract_crate();

let extra_derives = self.expand_extra_derives();
let enum_name = self.expand_event_enum_name();

quote! {
#[doc = "Container type for all of the contract's events"]
#[derive(Debug, Clone, PartialEq, Eq, #ethers_contract::EthAbiType, #extra_derives)]
#[derive(Clone, #ethers_contract::EthAbiType, #derives)]
pub enum #enum_name {
#( #variants(#variants), )*
}
Expand Down Expand Up @@ -191,15 +195,14 @@ impl Context {
let all_anonymous_fields = event.inputs.iter().all(|input| input.name.is_empty());
let data_type_definition = expand_event_struct(&struct_name, &fields, all_anonymous_fields);

let mut extra_derives = self.expand_extra_derives();
if event.inputs.iter().map(|param| &param.kind).all(util::can_derive_default) {
extra_derives.extend(quote!(Default));
}
let mut derives = self.expand_extra_derives();
let params = event.inputs.iter().map(|param| &param.kind);
util::derive_builtin_traits(params, &mut derives, true, true);

let ethers_contract = ethers_contract_crate();

Ok(quote! {
#[derive(Clone, Debug, Eq, PartialEq, #ethers_contract::EthEvent, #ethers_contract::EthDisplay, #extra_derives)]
#[derive(Clone, #ethers_contract::EthEvent, #ethers_contract::EthDisplay, #derives)]
#[ethevent(name = #name, abi = #abi_signature)]
pub #data_type_definition
})
Expand Down
25 changes: 13 additions & 12 deletions ethers-contract/ethers-contract-abigen/src/contract/methods.rs
Expand Up @@ -122,16 +122,15 @@ impl Context {
hex::encode(function.selector())
);

let mut extra_derives = self.expand_extra_derives();
if util::can_derive_defaults(&function.inputs) {
extra_derives.extend(quote!(Default));
}
let mut derives = self.expand_extra_derives();
let params = function.inputs.iter().map(|param| &param.kind);
util::derive_builtin_traits(params, &mut derives, true, true);

let ethers_contract = ethers_contract_crate();

Ok(quote! {
#[doc = #doc_str]
#[derive(Clone, Debug, Eq, PartialEq, #ethers_contract::EthCall, #ethers_contract::EthDisplay, #extra_derives)]
#[derive(Clone, #ethers_contract::EthCall, #ethers_contract::EthDisplay, #derives)]
#[ethcall( name = #function_name, abi = #abi_signature )]
pub #call_type_definition
})
Expand Down Expand Up @@ -162,16 +161,15 @@ impl Context {
hex::encode(function.selector())
);

let mut extra_derives = self.expand_extra_derives();
if util::can_derive_defaults(&function.inputs) {
extra_derives.extend(quote!(Default));
}
let mut derives = self.expand_extra_derives();
let params = function.inputs.iter().map(|param| &param.kind);
util::derive_builtin_traits(params, &mut derives, true, true);

let ethers_contract = ethers_contract_crate();

Ok(Some(quote! {
#[doc = #doc_str]
#[derive(Clone, Debug, Eq, PartialEq, #ethers_contract::EthAbiType, #ethers_contract::EthAbiCodec, #extra_derives)]
#[derive(Clone, #ethers_contract::EthAbiType, #ethers_contract::EthAbiCodec, #derives)]
pub #return_type_definition
}))
}
Expand All @@ -197,7 +195,10 @@ impl Context {
return Ok(struct_def_tokens)
}

let extra_derives = self.expand_extra_derives();
let mut derives = self.expand_extra_derives();
let params =
self.abi.functions.values().flatten().flat_map(|f| &f.inputs).map(|param| &param.kind);
util::derive_builtin_traits(params, &mut derives, false, true);

let enum_name = self.expand_calls_enum_name();

Expand All @@ -208,7 +209,7 @@ impl Context {
#struct_def_tokens

#[doc = "Container type for all of the contract's call "]
#[derive(Debug, Clone, PartialEq, Eq, #ethers_contract::EthAbiType, #extra_derives)]
#[derive(Clone, #ethers_contract::EthAbiType, #derives)]
pub enum #enum_name {
#( #variant_names(#struct_names), )*
}
Expand Down
31 changes: 14 additions & 17 deletions ethers-contract/ethers-contract-abigen/src/contract/structs.rs
Expand Up @@ -61,9 +61,9 @@ impl Context {
.internal_structs
.struct_tuples
.get(id)
.ok_or_else(|| eyre!("No types found for {id}"))?
.clone();
self.expand_internal_struct(struct_name, sol_struct, tuple)
.ok_or_else(|| eyre!("No types found for {id}"))?;
let types = if let ParamType::Tuple(types) = tuple { types } else { unreachable!() };
self.expand_internal_struct(struct_name, sol_struct, types)
}

/// Returns the `TokenStream` with all the internal structs extracted form the JSON ABI
Expand All @@ -83,7 +83,7 @@ impl Context {
&self,
name: &str,
sol_struct: &SolStruct,
tuple: ParamType,
types: &[ParamType],
) -> Result<TokenStream> {
let mut fields = Vec::with_capacity(sol_struct.fields().len());

Expand Down Expand Up @@ -112,19 +112,17 @@ impl Context {

let struct_def = expand_struct(&name, &fields, is_tuple);

let sig = match tuple {
ParamType::Tuple(ref types) if !types.is_empty() => util::abi_signature_types(types),
_ => String::new(),
};
let sig = util::abi_signature_types(types);
let doc_str = format!("`{name}({sig})`");

let extra_derives = self.expand_extra_derives();
let mut derives = self.expand_extra_derives();
util::derive_builtin_traits_struct(&self.internal_structs, sol_struct, types, &mut derives);

let ethers_contract = ethers_contract_crate();

Ok(quote! {
#[doc = #doc_str]
#[derive(Clone, Debug, Default, Eq, PartialEq, #ethers_contract::EthAbiType, #ethers_contract::EthAbiCodec, #extra_derives)]
#[derive(Clone, #ethers_contract::EthAbiType, #ethers_contract::EthAbiCodec, #derives)]
pub #struct_def
})
}
Expand Down Expand Up @@ -167,16 +165,14 @@ impl Context {

let name = util::ident(name);

let mut extra_derives = self.expand_extra_derives();
if param_types.iter().all(util::can_derive_default) {
extra_derives.extend(quote!(Default))
}
let mut derives = self.expand_extra_derives();
util::derive_builtin_traits(&param_types, &mut derives, true, true);

let ethers_contract = ethers_contract_crate();

Ok(quote! {
#[doc = #abi_signature]
#[derive(Clone, Debug, Eq, PartialEq, #ethers_contract::EthAbiType, #ethers_contract::EthAbiCodec, #extra_derives)]
#[derive(Clone, #ethers_contract::EthAbiType, #ethers_contract::EthAbiCodec, #derives)]
pub struct #name {
#( #fields ),*
}
Expand Down Expand Up @@ -231,7 +227,7 @@ impl InternalStructs {
let mut function_params = HashMap::new();
let mut outputs = HashMap::new();
let mut event_params = HashMap::new();
let mut structs = HashMap::new();

for item in abi
.into_iter()
.filter(|item| matches!(item.type_field.as_str(), "constructor" | "function" | "event"))
Expand Down Expand Up @@ -279,6 +275,7 @@ impl InternalStructs {

// turn each top level internal type (function input/output) and their nested types
// into a struct will create all structs
let mut structs = HashMap::new();
for component in top_level_internal_types.values() {
insert_structs(&mut structs, component);
}
Expand Down Expand Up @@ -569,7 +566,7 @@ fn struct_type_name(name: &str) -> &str {
struct_type_identifier(name).rsplit('.').next().unwrap()
}

/// `Pairing.G2Point` -> `Pairing.G2Point`
/// `struct Pairing.G2Point[]` -> `Pairing.G2Point`
fn struct_type_identifier(name: &str) -> &str {
name.trim_start_matches("struct ").split('[').next().unwrap()
}
Expand Down
8 changes: 4 additions & 4 deletions ethers-contract/ethers-contract-abigen/src/multi.rs
Expand Up @@ -1342,7 +1342,7 @@ contract Enum {
[package]
name = "ethers-contract"
version = "1.0.0"
edition = "2018"
edition = "2021"
rust-version = "1.64"
authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
license = "MIT OR Apache-2.0"
Expand Down Expand Up @@ -1388,7 +1388,7 @@ contract Enum {
[package]
name = "ethers-contract"
version = "1.0.0"
edition = "2018"
edition = "2021"
rust-version = "1.64"
authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
license = "MIT OR Apache-2.0"
Expand Down Expand Up @@ -1435,7 +1435,7 @@ contract Enum {
[package]
name = "ethers-contract"
version = "1.0.0"
edition = "2018"
edition = "2021"
rust-version = "1.64"
authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
license = "MIT OR Apache-2.0"
Expand Down Expand Up @@ -1482,7 +1482,7 @@ contract Enum {
[package]
name = "ethers-contract"
version = "1.0.0"
edition = "2018"
edition = "2021"
rust-version = "1.64"
authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
license = "MIT OR Apache-2.0"
Expand Down

0 comments on commit 3732de8

Please sign in to comment.