refactor(abigen): inline docs (#2090)
* refactor: abigen docs * chore: doc * refactor: final doc * mergings * fix: unremove Default
This commit is contained in:
parent
93e1850646
commit
fd02bbc418
|
@ -62,7 +62,7 @@ where
|
|||
}
|
||||
|
||||
pub(crate) fn imports(name: &str) -> TokenStream {
|
||||
let doc = util::expand_doc(&format!("{name} was auto-generated with ethers-rs Abigen. More information at: https://github.com/gakonst/ethers-rs"));
|
||||
let doc_str = format!("{name} was auto-generated with ethers-rs Abigen. More information at: https://github.com/gakonst/ethers-rs");
|
||||
|
||||
let ethers_core = ethers_core_crate();
|
||||
let ethers_providers = ethers_providers_crate();
|
||||
|
@ -73,7 +73,7 @@ pub(crate) fn imports(name: &str) -> TokenStream {
|
|||
#![allow(dead_code)]
|
||||
#![allow(clippy::type_complexity)]
|
||||
#![allow(unused_imports)]
|
||||
#doc
|
||||
#![doc = #doc_str]
|
||||
|
||||
use std::sync::Arc;
|
||||
use #ethers_core::{
|
||||
|
|
|
@ -59,13 +59,12 @@ impl Context {
|
|||
expand_data_struct(&error_name, &fields)
|
||||
};
|
||||
|
||||
let doc = format!(
|
||||
let doc_str = format!(
|
||||
"Custom Error type `{}` with signature `{}` and selector `0x{}`",
|
||||
error.name,
|
||||
abi_signature,
|
||||
hex::encode(&error.selector()[..])
|
||||
);
|
||||
let abi_signature_doc = util::expand_doc(&doc);
|
||||
let ethers_contract = ethers_contract_crate();
|
||||
// use the same derives as for events
|
||||
let derives = util::expand_derives(&self.event_derives);
|
||||
|
@ -73,7 +72,7 @@ impl Context {
|
|||
let error_name = &error.name;
|
||||
|
||||
Ok(quote! {
|
||||
#abi_signature_doc
|
||||
#[doc = #doc_str]
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, #ethers_contract::EthError, #ethers_contract::EthDisplay, #derives)]
|
||||
#[etherror(name = #error_name, abi = #abi_signature)]
|
||||
pub #data_type_definition
|
||||
|
|
|
@ -217,24 +217,25 @@ impl Context {
|
|||
|
||||
/// Expands into a single method for contracting an event stream.
|
||||
fn expand_filter(&self, event: &Event) -> TokenStream {
|
||||
let ethers_contract = ethers_contract_crate();
|
||||
let name = &event.name;
|
||||
let alias = self.event_aliases.get(&event.abi_signature()).cloned();
|
||||
|
||||
let name = if let Some(id) = alias.clone() {
|
||||
// append `filter` to disambiguate with potentially conflicting
|
||||
// function names
|
||||
let function_name = if let Some(id) = alias.clone() {
|
||||
util::safe_ident(&format!("{}_filter", id.to_string().to_snake_case()))
|
||||
} else {
|
||||
util::safe_ident(&format!("{}_filter", event.name.to_snake_case()))
|
||||
};
|
||||
let struct_name = event_struct_name(name, alias);
|
||||
|
||||
// append `filter` to disambiguate with potentially conflicting
|
||||
// function names
|
||||
let doc_str = format!("Gets the contract's `{name}` event");
|
||||
|
||||
let result = event_struct_name(&event.name, alias);
|
||||
let ethers_contract = ethers_contract_crate();
|
||||
|
||||
let doc = util::expand_doc(&format!("Gets the contract's `{}` event", event.name));
|
||||
quote! {
|
||||
#doc
|
||||
pub fn #name(&self) -> #ethers_contract::builders::Event<M, #result> {
|
||||
#[doc = #doc_str]
|
||||
pub fn #function_name(&self) -> #ethers_contract::builders::Event<M, #struct_name> {
|
||||
self.0.event()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -124,13 +124,11 @@ impl Context {
|
|||
};
|
||||
let function_name = &function.name;
|
||||
let abi_signature = function.abi_signature();
|
||||
let doc = format!(
|
||||
"Container type for all input parameters for the `{}` function with signature `{}` and selector `0x{}`",
|
||||
function.name,
|
||||
abi_signature,
|
||||
let doc_str = format!(
|
||||
"Container type for all input parameters for the `{function_name}` function with signature `{abi_signature}` and selector `0x{}`",
|
||||
hex::encode(&function.selector()[..])
|
||||
);
|
||||
let abi_signature_doc = util::expand_doc(&doc);
|
||||
|
||||
let ethers_contract = ethers_contract_crate();
|
||||
// use the same derives as for events
|
||||
let derives = util::expand_derives(&self.event_derives);
|
||||
|
@ -146,7 +144,7 @@ impl Context {
|
|||
};
|
||||
|
||||
Ok(quote! {
|
||||
#abi_signature_doc
|
||||
#[doc = #doc_str]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, #ethers_contract::EthCall, #ethers_contract::EthDisplay, #derives)]
|
||||
#derive_default
|
||||
#[ethcall( name = #function_name, abi = #abi_signature )]
|
||||
|
@ -160,6 +158,7 @@ impl Context {
|
|||
function: &Function,
|
||||
alias: Option<&MethodAlias>,
|
||||
) -> Result<TokenStream> {
|
||||
let name = &function.name;
|
||||
let struct_name = expand_return_struct_name(function, alias);
|
||||
let fields = self.expand_output_params(function)?;
|
||||
// no point in having structs when there is no data returned
|
||||
|
@ -176,13 +175,11 @@ impl Context {
|
|||
expand_data_struct(&struct_name, &fields)
|
||||
};
|
||||
let abi_signature = function.abi_signature();
|
||||
let doc = format!(
|
||||
"Container type for all return fields from the `{}` function with signature `{}` and selector `0x{}`",
|
||||
function.name,
|
||||
abi_signature,
|
||||
let doc_str = format!(
|
||||
"Container type for all return fields from the `{name}` function with signature `{abi_signature}` and selector `0x{}`",
|
||||
hex::encode(&function.selector()[..])
|
||||
);
|
||||
let abi_signature_doc = util::expand_doc(&doc);
|
||||
|
||||
let ethers_contract = ethers_contract_crate();
|
||||
// use the same derives as for events
|
||||
let derives = util::expand_derives(&self.event_derives);
|
||||
|
@ -198,7 +195,7 @@ impl Context {
|
|||
};
|
||||
|
||||
Ok(quote! {
|
||||
#abi_signature_doc
|
||||
#[doc = #doc_str]
|
||||
#[derive(Clone, Debug,Eq, PartialEq, #ethers_contract::EthAbiType, #ethers_contract::EthAbiCodec, #derives)]
|
||||
#derive_default
|
||||
pub #return_type_definition
|
||||
|
@ -436,10 +433,11 @@ impl Context {
|
|||
function: &Function,
|
||||
alias: Option<MethodAlias>,
|
||||
) -> Result<TokenStream> {
|
||||
let ethers_contract = ethers_contract_crate();
|
||||
let name = &function.name;
|
||||
let function_name = expand_function_name(function, alias.as_ref());
|
||||
let selector = function.selector();
|
||||
|
||||
let name = expand_function_name(function, alias.as_ref());
|
||||
let selector = expand_selector(function.selector());
|
||||
let selector_tokens = expand_selector(selector);
|
||||
|
||||
let contract_args = self.expand_contract_call_args(function)?;
|
||||
let function_params =
|
||||
|
@ -448,18 +446,15 @@ impl Context {
|
|||
|
||||
let outputs = self.expand_outputs(function)?;
|
||||
|
||||
let result = quote! { #ethers_contract::builders::ContractCall<M, #outputs> };
|
||||
let doc_str =
|
||||
format!("Calls the contract's `{name}` (0x{}) function", hex::encode(selector));
|
||||
|
||||
let ethers_contract = ethers_contract_crate();
|
||||
|
||||
let doc = util::expand_doc(&format!(
|
||||
"Calls the contract's `{}` (0x{}) function",
|
||||
function.name,
|
||||
hex::encode(function.selector())
|
||||
));
|
||||
Ok(quote! {
|
||||
|
||||
#doc
|
||||
pub fn #name(&self #function_params) -> #result {
|
||||
self.0.method_hash(#selector, #contract_args)
|
||||
#[doc = #doc_str]
|
||||
pub fn #function_name(&self #function_params) -> #ethers_contract::builders::ContractCall<M, #outputs> {
|
||||
self.0.method_hash(#selector_tokens, #contract_args)
|
||||
.expect("method not found (this should never happen)")
|
||||
}
|
||||
})
|
||||
|
@ -470,9 +465,10 @@ impl Context {
|
|||
///
|
||||
/// In case of overloaded functions we would follow rust's general
|
||||
/// convention of suffixing the function name with _with
|
||||
// The first function or the function with the least amount of arguments should
|
||||
// be named as in the ABI, the following functions suffixed with _with_ +
|
||||
// additional_params[0].name + (_and_(additional_params[1+i].name))*
|
||||
///
|
||||
/// The first function or the function with the least amount of arguments should
|
||||
/// be named as in the ABI, the following functions suffixed with _with_ +
|
||||
/// additional_params[0].name + (_and_(additional_params[1+i].name))*
|
||||
fn get_method_aliases(&self) -> Result<BTreeMap<String, MethodAlias>> {
|
||||
let mut aliases = self.method_aliases.clone();
|
||||
|
||||
|
|
|
@ -123,22 +123,18 @@ impl Context {
|
|||
}
|
||||
};
|
||||
|
||||
let sig = if let ParamType::Tuple(ref tokens) = tuple {
|
||||
tokens.iter().map(|kind| kind.to_string()).collect::<Vec<_>>().join(",")
|
||||
} else {
|
||||
"".to_string()
|
||||
let sig = match tuple {
|
||||
ParamType::Tuple(ref types) if !types.is_empty() => util::abi_signature_types(types),
|
||||
_ => String::new(),
|
||||
};
|
||||
|
||||
let abi_signature = format!("{name}({sig})",);
|
||||
|
||||
let abi_signature_doc = util::expand_doc(&format!("`{abi_signature}`"));
|
||||
let doc_str = format!("`{name}({sig})`");
|
||||
|
||||
// use the same derives as for events
|
||||
let derives = util::expand_derives(&self.event_derives);
|
||||
|
||||
let ethers_contract = ethers_contract_crate();
|
||||
Ok(quote! {
|
||||
#abi_signature_doc
|
||||
#[doc = #doc_str]
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, #ethers_contract::EthAbiType, #ethers_contract::EthAbiCodec, #derives)]
|
||||
#struct_def
|
||||
})
|
||||
|
@ -178,13 +174,7 @@ impl Context {
|
|||
}
|
||||
}
|
||||
|
||||
let abi_signature = format!(
|
||||
"{}({})",
|
||||
name,
|
||||
param_types.iter().map(|kind| kind.to_string()).collect::<Vec<_>>().join(","),
|
||||
);
|
||||
|
||||
let abi_signature_doc = util::expand_doc(&format!("`{abi_signature}`"));
|
||||
let abi_signature = util::abi_signature(name, ¶m_types);
|
||||
|
||||
let name = util::ident(name);
|
||||
|
||||
|
@ -195,7 +185,7 @@ impl Context {
|
|||
let ethers_contract = ethers_contract_crate();
|
||||
|
||||
Ok(quote! {
|
||||
#abi_signature_doc
|
||||
#[doc = #abi_signature]
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, #ethers_contract::EthAbiType, #ethers_contract::EthAbiCodec, #derives)]
|
||||
pub struct #name {
|
||||
#( #fields ),*
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use ethers_core::abi::{Param, ParamType};
|
||||
use eyre::Result;
|
||||
use inflector::Inflector;
|
||||
use proc_macro2::{Ident, Literal, Span, TokenStream};
|
||||
use proc_macro2::{Ident, Span, TokenStream};
|
||||
use quote::quote;
|
||||
use std::path::PathBuf;
|
||||
use syn::{Ident as SynIdent, Path};
|
||||
|
@ -81,14 +81,6 @@ pub fn expand_input_name(index: usize, name: &str) -> TokenStream {
|
|||
quote! { #name }
|
||||
}
|
||||
|
||||
/// Expands a doc string into an attribute token stream.
|
||||
pub fn expand_doc(s: &str) -> TokenStream {
|
||||
let doc = Literal::string(s);
|
||||
quote! {
|
||||
#[doc = #doc]
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expand_derives(derives: &[Path]) -> TokenStream {
|
||||
quote! {#(#derives),*}
|
||||
}
|
||||
|
@ -167,13 +159,16 @@ pub fn json_files(root: impl AsRef<std::path::Path>) -> Vec<PathBuf> {
|
|||
.collect()
|
||||
}
|
||||
|
||||
/// rust-std derives `Default` automatically only for arrays len <= 32
|
||||
/// Returns whether all the given parameters can derive [`Default`].
|
||||
///
|
||||
/// Returns whether the corresponding struct can derive `Default`
|
||||
pub fn can_derive_defaults(params: &[Param]) -> bool {
|
||||
params.iter().map(|param| ¶m.kind).all(can_derive_default)
|
||||
/// rust-std derives `Default` automatically only for arrays len <= 32
|
||||
pub fn can_derive_defaults<'a>(params: impl IntoIterator<Item = &'a Param>) -> bool {
|
||||
params.into_iter().map(|param| ¶m.kind).all(can_derive_default)
|
||||
}
|
||||
|
||||
/// Returns whether the given type can derive [`Default`].
|
||||
///
|
||||
/// rust-std derives `Default` automatically only for arrays len <= 32
|
||||
pub fn can_derive_default(param: &ParamType) -> bool {
|
||||
const MAX_SUPPORTED_LEN: usize = 32;
|
||||
match param {
|
||||
|
@ -190,6 +185,21 @@ pub fn can_derive_default(param: &ParamType) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the formatted Solidity ABI signature.
|
||||
pub fn abi_signature<'a, N, T>(name: N, types: T) -> String
|
||||
where
|
||||
N: std::fmt::Display,
|
||||
T: IntoIterator<Item = &'a ParamType>,
|
||||
{
|
||||
let types = abi_signature_types(types);
|
||||
format!("`{name}({types})`")
|
||||
}
|
||||
|
||||
/// Returns the Solidity stringified ABI types joined by a single comma.
|
||||
pub fn abi_signature_types<'a, T: IntoIterator<Item = &'a ParamType>>(types: T) -> String {
|
||||
types.into_iter().map(ToString::to_string).collect::<Vec<_>>().join(",")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
Loading…
Reference in New Issue