docs(abigen): rename `event_derives` to `derives` (#2018)

* chore: rename event_derives to derives

Misleading name, `event_derives` implies that only Solidity events'
structs would apply, while this is not true

* last derive

* mv

* docs

* docs

* last doc
This commit is contained in:
DaniPopes 2023-01-13 19:17:32 +01:00 committed by GitHub
parent 2eb56e69b7
commit 79f27e2366
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 73 additions and 66 deletions

View File

@ -271,7 +271,7 @@ impl Context {
} }
let event_derives = args let event_derives = args
.event_derives .derives
.iter() .iter()
.map(|derive| syn::parse_str::<Path>(derive)) .map(|derive| syn::parse_str::<Path>(derive))
.collect::<Result<Vec<_>, _>>() .collect::<Result<Vec<_>, _>>()

View File

@ -1,9 +1,13 @@
#![deny(missing_docs, unsafe_code)] //! # Abigen
#![deny(rustdoc::broken_intra_doc_links)] //!
//! Programmatically generate type-safe Rust bindings for Ethereum smart contracts.
//!
//! This crate is intended to be used either indirectly with the [`abigen` procedural macro][abigen]
//! or directly from a build script / CLI.
//!
//! [abigen]: https://docs.rs/ethers/latest/ethers/contract/macro.abigen.html
//! Module for generating type-safe bindings to Ethereum smart contracts. This #![deny(rustdoc::broken_intra_doc_links, missing_docs, unsafe_code)]
//! module is intended to be used either indirectly with the `abigen` procedural
//! macro or directly from a build script / CLI
#[cfg(test)] #[cfg(test)]
#[allow(missing_docs)] #[allow(missing_docs)]
@ -33,19 +37,21 @@ use eyre::Result;
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use std::{collections::HashMap, fs::File, io::Write, path::Path}; use std::{collections::HashMap, fs::File, io::Write, path::Path};
/// Builder struct for generating type-safe bindings from a contract's ABI /// Programmatically generate type-safe Rust bindings for an Ethereum smart contract from its ABI.
/// ///
/// Note: Your contract's ABI must contain the `stateMutability` field. This is /// For all the supported ABI sources, see [Source].
/// [still not supported by Vyper](https://github.com/vyperlang/vyper/issues/1931), so you must adjust your ABIs and replace
/// `constant` functions with `view` or `pure`.
/// ///
/// To generate bindings for _multiple_ contracts at once see also [`crate::MultiAbigen`]. /// To generate bindings for *multiple* contracts at once, see [`MultiAbigen`].
///
/// To generate bindings at compile time, see [the abigen! macro][abigen], or use in a `build.rs`
/// file.
///
/// [abigen]: https://docs.rs/ethers/latest/ethers/contract/macro.abigen.html
/// ///
/// # Example /// # Example
/// ///
/// Running the code below will generate a file called `token.rs` containing the /// Running the code below will generate a file called `token.rs` containing the bindings inside,
/// bindings inside, which exports an `ERC20Token` struct, along with all its events. Put into a /// which exports an `ERC20Token` struct, along with all its events.
/// `build.rs` file this will generate the bindings during `cargo build`.
/// ///
/// ```no_run /// ```no_run
/// # use ethers_contract_abigen::Abigen; /// # use ethers_contract_abigen::Abigen;
@ -53,22 +59,22 @@ use std::{collections::HashMap, fs::File, io::Write, path::Path};
/// Abigen::new("ERC20Token", "./abi.json")?.generate()?.write_to_file("token.rs")?; /// Abigen::new("ERC20Token", "./abi.json")?.generate()?.write_to_file("token.rs")?;
/// # Ok(()) /// # Ok(())
/// # } /// # }
#[derive(Debug, Clone)] #[derive(Clone, Debug)]
#[must_use = "Abigen does nothing unless you generate or expand it."]
pub struct Abigen { pub struct Abigen {
/// The source of the ABI JSON for the contract whose bindings /// The source of the ABI JSON for the contract whose bindings are being generated.
/// are being generated.
abi_source: Source, abi_source: Source,
/// Override the contract name to use for the generated type. /// The contract's name to use for the generated type.
contract_name: String, contract_name: String,
/// Manually specified contract method aliases. /// Manually specified contract method aliases.
method_aliases: HashMap<String, String>, method_aliases: HashMap<String, String>,
/// Derives added to event structs and enums. /// Manually specified `derive` macros added to all structs and enums.
event_derives: Vec<String>, derives: Vec<String>,
/// Whether to format the code. Uses [`prettyplease`]. /// Whether to format the generated bindings using [`prettyplease`].
format: bool, format: bool,
/// Manually specified event name aliases. /// Manually specified event name aliases.
@ -79,22 +85,21 @@ pub struct Abigen {
} }
impl Abigen { impl Abigen {
/// Creates a new builder with the given ABI JSON source. /// Creates a new builder with the given [ABI Source][Source].
pub fn new<S: AsRef<str>>(contract_name: &str, abi_source: S) -> Result<Self> { pub fn new<T: Into<String>, S: AsRef<str>>(contract_name: T, abi_source: S) -> Result<Self> {
let abi_source = abi_source.as_ref().parse()?; let abi_source = abi_source.as_ref().parse()?;
Ok(Self { Ok(Self {
abi_source, abi_source,
contract_name: contract_name.to_owned(), contract_name: contract_name.into(),
method_aliases: HashMap::new(),
event_derives: Vec::new(),
event_aliases: HashMap::new(),
format: true, format: true,
method_aliases: Default::default(),
derives: Default::default(),
event_aliases: Default::default(),
error_aliases: Default::default(), error_aliases: Default::default(),
}) })
} }
/// Attempts to load a new builder from an ABI JSON file at the specific /// Attempts to load a new builder from an ABI JSON file at the specific path.
/// path.
pub fn from_file(path: impl AsRef<Path>) -> Result<Self> { pub fn from_file(path: impl AsRef<Path>) -> Result<Self> {
let name = path let name = path
.as_ref() .as_ref()
@ -110,9 +115,10 @@ impl Abigen {
Self::new(name, std::fs::read_to_string(path.as_ref())?) Self::new(name, std::fs::read_to_string(path.as_ref())?)
} }
/// Manually adds a solidity event alias to specify what the event struct /// Manually adds a solidity event alias to specify what the event struct and function name will
/// and function name will be in Rust. /// be in Rust.
#[must_use] ///
/// For events without an alias, the `PascalCase` event name will be used.
pub fn add_event_alias<S1, S2>(mut self, signature: S1, alias: S2) -> Self pub fn add_event_alias<S1, S2>(mut self, signature: S1, alias: S2) -> Self
where where
S1: Into<String>, S1: Into<String>,
@ -122,10 +128,9 @@ impl Abigen {
self self
} }
/// Manually adds a solidity method alias to specify what the method name /// Add a Solidity method error alias to specify the generated method name.
/// will be in Rust. For solidity methods without an alias, the snake cased ///
/// method name will be used. /// For methods without an alias, the `snake_case` method name will be used.
#[must_use]
pub fn add_method_alias<S1, S2>(mut self, signature: S1, alias: S2) -> Self pub fn add_method_alias<S1, S2>(mut self, signature: S1, alias: S2) -> Self
where where
S1: Into<String>, S1: Into<String>,
@ -135,8 +140,9 @@ impl Abigen {
self self
} }
/// Manually adds a solidity error alias to specify what the error struct will be in Rust. /// Add a Solidity custom error alias to specify the generated struct's name.
#[must_use] ///
/// For errors without an alias, the `PascalCase` error name will be used.
pub fn add_error_alias<S1, S2>(mut self, signature: S1, alias: S2) -> Self pub fn add_error_alias<S1, S2>(mut self, signature: S1, alias: S2) -> Self
where where
S1: Into<String>, S1: Into<String>,
@ -163,16 +169,18 @@ impl Abigen {
self self
} }
/// Add a custom derive to the derives for event structs and enums. #[deprecated = "Use add_derive instead"]
#[doc(hidden)]
pub fn add_event_derive<S: Into<String>>(mut self, derive: S) -> Self {
self.derives.push(derive.into());
self
}
/// Add a custom derive to the derives for all structs and enums.
/// ///
/// This makes it possible to for example derive serde::Serialize and /// For example, this makes it possible to derive serde::Serialize and serde::Deserialize.
/// serde::Deserialize for events. pub fn add_derive<S: Into<String>>(mut self, derive: S) -> Self {
#[must_use] self.derives.push(derive.into());
pub fn add_event_derive<S>(mut self, derive: S) -> Self
where
S: Into<String>,
{
self.event_derives.push(derive.into());
self self
} }
@ -253,12 +261,12 @@ impl ContractBindings {
self.tokens self.tokens
} }
/// Generate the default module name (snake case of the contract name) /// Generate the default module name (snake case of the contract name).
pub fn module_name(&self) -> String { pub fn module_name(&self) -> String {
util::safe_module_name(&self.name) util::safe_module_name(&self.name)
} }
/// Generate the default filename of the module /// Generate the default file name of the module.
pub fn module_filename(&self) -> String { pub fn module_filename(&self) -> String {
let mut name = self.module_name(); let mut name = self.module_name();
name.extend([".rs"]); name.extend([".rs"]);

View File

@ -1,14 +1,13 @@
//! Implementation of procedural macro for generating type-safe bindings to an //! Implementation of procedural macro for generating type-safe bindings to an Ethereum smart
//! ethereum smart contract. //! contract.
use crate::spanned::{ParseInner, Spanned}; use crate::spanned::{ParseInner, Spanned};
use ethers_contract_abigen::Abigen;
use ethers_core::abi::{Function, FunctionExt, Param, StateMutability};
use ethers_contract_abigen::{ use ethers_contract_abigen::{
contract::{Context, ExpandedContract}, contract::{Context, ExpandedContract},
multi::MultiExpansion, multi::MultiExpansion,
Abigen,
}; };
use ethers_core::abi::{Function, FunctionExt, Param, StateMutability};
use proc_macro2::{Span, TokenStream as TokenStream2}; use proc_macro2::{Span, TokenStream as TokenStream2};
use quote::ToTokens; use quote::ToTokens;
use std::{collections::HashSet, error::Error}; use std::{collections::HashSet, error::Error};
@ -75,9 +74,9 @@ impl ContractArgs {
Parameter::Methods(methods) => methods Parameter::Methods(methods) => methods
.into_iter() .into_iter()
.fold(builder, |builder, m| builder.add_method_alias(m.signature, m.alias)), .fold(builder, |builder, m| builder.add_method_alias(m.signature, m.alias)),
Parameter::EventDerives(derives) => derives Parameter::Derives(derives) => {
.into_iter() derives.into_iter().fold(builder, |builder, derive| builder.add_derive(derive))
.fold(builder, |builder, derive| builder.add_event_derive(derive)), }
}; };
} }
@ -133,7 +132,7 @@ impl ParseInner for ContractArgs {
#[cfg_attr(test, derive(Debug, Eq, PartialEq))] #[cfg_attr(test, derive(Debug, Eq, PartialEq))]
enum Parameter { enum Parameter {
Methods(Vec<Method>), Methods(Vec<Method>),
EventDerives(Vec<String>), Derives(Vec<String>),
} }
impl Parse for Parameter { impl Parse for Parameter {
@ -171,7 +170,7 @@ impl Parse for Parameter {
Parameter::Methods(methods) Parameter::Methods(methods)
} }
"event_derives" => { "derives" | "event_derives" => {
let content; let content;
parenthesized!(content in input); parenthesized!(content in input);
let derives = content let derives = content
@ -179,7 +178,7 @@ impl Parse for Parameter {
.into_iter() .into_iter()
.map(|path| path.to_token_stream().to_string()) .map(|path| path.to_token_stream().to_string())
.collect(); .collect();
Parameter::EventDerives(derives) Parameter::Derives(derives)
} }
_ => { _ => {
return Err(ParseError::new( return Err(ParseError::new(
@ -295,7 +294,7 @@ mod tests {
ContractArgs { ContractArgs {
name: "TestContract".to_string(), name: "TestContract".to_string(),
abi: "path/to/abi.json".to_string(), abi: "path/to/abi.json".to_string(),
parameters: vec![Parameter::EventDerives(vec![ parameters: vec![Parameter::Derives(vec![
"serde :: Deserialize".into(), "serde :: Deserialize".into(),
"serde :: Serialize".into(), "serde :: Serialize".into(),
])], ])],
@ -303,7 +302,7 @@ mod tests {
ContractArgs { ContractArgs {
name: "TestContract2".to_string(), name: "TestContract2".to_string(),
abi: "other.json".to_string(), abi: "other.json".to_string(),
parameters: vec![Parameter::EventDerives(vec![ parameters: vec![Parameter::Derives(vec![
"serde :: Deserialize".into(), "serde :: Deserialize".into(),
"serde :: Serialize".into(), "serde :: Serialize".into(),
])], ])],
@ -341,7 +340,7 @@ mod tests {
ContractArgs { ContractArgs {
name: "TestContract2".to_string(), name: "TestContract2".to_string(),
abi: "other.json".to_string(), abi: "other.json".to_string(),
parameters: vec![Parameter::EventDerives(vec![ parameters: vec![Parameter::Derives(vec![
"serde :: Deserialize".into(), "serde :: Deserialize".into(),
"serde :: Serialize".into(), "serde :: Serialize".into(),
])], ])],
@ -372,7 +371,7 @@ mod tests {
ContractArgs { ContractArgs {
name: "TestContract2".to_string(), name: "TestContract2".to_string(),
abi: "other.json".to_string(), abi: "other.json".to_string(),
parameters: vec![Parameter::EventDerives(vec![ parameters: vec![Parameter::Derives(vec![
"serde :: Deserialize".into(), "serde :: Deserialize".into(),
"serde :: Serialize".into(), "serde :: Serialize".into(),
])], ])],
@ -423,7 +422,7 @@ mod tests {
method("myMethod(uint256,bool)", "my_renamed_method"), method("myMethod(uint256,bool)", "my_renamed_method"),
method("myOtherMethod()", "my_other_renamed_method"), method("myOtherMethod()", "my_other_renamed_method"),
]), ]),
Parameter::EventDerives(vec![ Parameter::Derives(vec![
"Asdf".into(), "Asdf".into(),
"a :: B".into(), "a :: B".into(),
"a :: b :: c :: D".into() "a :: b :: c :: D".into()