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:
parent
2eb56e69b7
commit
79f27e2366
|
@ -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<_>, _>>()
|
||||||
|
|
|
@ -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"]);
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in New Issue