chore: bump syn to 2.0, fix breaking changes

This commit is contained in:
DaniPopes 2023-03-18 16:54:53 +01:00
parent d5831b2679
commit ef5a37b2e5
No known key found for this signature in database
GPG Key ID: 0F09640DDB7AC692
7 changed files with 166 additions and 307 deletions

83
Cargo.lock generated
View File

@ -104,7 +104,7 @@ checksum = "b84f9ebcc6c1f5b8cb160f6990096a5c127f423fcb6e1ccc46c370cbdfb75dfc"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -138,7 +138,7 @@ dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -485,7 +485,7 @@ dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -821,7 +821,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096"
dependencies = [
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -872,7 +872,7 @@ dependencies = [
"proc-macro2",
"quote",
"scratch",
"syn",
"syn 1.0.109",
]
[[package]]
@ -889,7 +889,7 @@ checksum = "0b75aed41bb2e6367cae39e6326ef817a851db13c13e4f3263714ca3cfb8de56"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -932,7 +932,7 @@ checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -1272,7 +1272,7 @@ dependencies = [
"reqwest",
"serde",
"serde_json",
"syn",
"syn 2.0.0",
"tempfile",
"tokio",
"toml",
@ -1289,7 +1289,7 @@ dependencies = [
"hex",
"proc-macro2",
"quote",
"syn",
"syn 2.0.0",
]
[[package]]
@ -1312,13 +1312,12 @@ dependencies = [
"num_enum",
"once_cell",
"open-fastrlp",
"proc-macro2",
"rand",
"rlp",
"serde",
"serde_json",
"strum",
"syn",
"syn 2.0.0",
"tempfile",
"thiserror",
"tiny-keccak",
@ -1332,9 +1331,10 @@ dependencies = [
"ethers-contract-derive",
"ethers-core",
"hex",
"proc-macro2",
"quote",
"serde_json",
"syn",
"syn 2.0.0",
]
[[package]]
@ -1816,7 +1816,7 @@ checksum = "3eb14ed937631bd8b8b8977f2c198443447a8355b6e3ca599f38c975e5a963b6"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -2204,7 +2204,7 @@ checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -2615,7 +2615,7 @@ dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -2664,7 +2664,7 @@ dependencies = [
"bytes",
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -2690,7 +2690,7 @@ checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -2790,7 +2790,7 @@ dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -2911,7 +2911,7 @@ dependencies = [
"phf_shared 0.11.1",
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -2955,7 +2955,7 @@ checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -3051,7 +3051,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86"
dependencies = [
"proc-macro2",
"syn",
"syn 1.0.109",
]
[[package]]
@ -3096,7 +3096,7 @@ dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
"version_check",
]
@ -3340,7 +3340,7 @@ checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -3549,7 +3549,7 @@ dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -3687,7 +3687,7 @@ checksum = "d7e29c4601e36bcec74a223228dce795f4cd3616341a4af93520ca1a837c087d"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -3753,7 +3753,7 @@ checksum = "079a83df15f85d89a68d64ae1238f142f172b1fa915d0d76b26a7cba1b659a69"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -3844,7 +3844,7 @@ checksum = "ede930749cca4e3a3df7e37b5f0934a55693e01d028d7a4e506b44cbc059d95a"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -3951,7 +3951,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustversion",
"syn",
"syn 1.0.109",
]
[[package]]
@ -4015,6 +4015,17 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "syn"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cff13bb1732bccfe3b246f3fdb09edfd51c01d6f5299b7ccd9457c2e4e37774"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "synstructure"
version = "0.12.6"
@ -4023,7 +4034,7 @@ checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
"unicode-xid",
]
@ -4099,7 +4110,7 @@ checksum = "5420d42e90af0c38c3290abcca25b9b3bdf379fc9f55c528f53a269d9c9a267e"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -4200,7 +4211,7 @@ checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -4316,7 +4327,7 @@ checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -4388,7 +4399,7 @@ checksum = "258bc1c4f8e2e73a977812ab339d503e6feeb92700f6d07a6de4d321522d5c08"
dependencies = [
"lazy_static",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -4600,7 +4611,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
"wasm-bindgen-shared",
]
@ -4634,7 +4645,7 @@ checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@ -4919,7 +4930,7 @@ checksum = "44bf07cb3e50ea2003396695d58bf46bc9887a1f362260446fad6bc4e79bd36c"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
"synstructure",
]

View File

@ -107,7 +107,7 @@ serde_json = "1.0"
# macros
proc-macro2 = "1.0"
quote = "1.0"
syn = { version = "1.0", features = ["extra-traits"] }
syn = { version = "2.0", features = ["extra-traits"] }
async-trait = "0.1.66"
auto_impl = "1.0"

View File

@ -30,7 +30,7 @@ ethers-core = { workspace = true, features = ["macros"] }
proc-macro2.workspace = true
quote.workspace = true
syn.workspace = true
syn = { workspace = true, features = ["full"] }
prettyplease = "0.1.25"
Inflector = "0.11"

View File

@ -55,7 +55,6 @@ cargo_metadata = { version = "0.15.3", optional = true }
# eip712 feature enabled dependencies
convert_case = { version = "0.6.0", optional = true }
syn = { workspace = true, optional = true }
proc-macro2 = { workspace = true, optional = true }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
tempfile.workspace = true
@ -73,5 +72,5 @@ rand.workspace = true
[features]
celo = ["legacy"] # celo support extends the transaction format with extra fields
legacy = []
eip712 = ["convert_case", "syn", "proc-macro2"]
eip712 = ["convert_case", "syn"]
macros = ["syn", "cargo_metadata", "once_cell"]

View File

@ -19,6 +19,7 @@ proc-macro = true
[dependencies]
ethers-core = { workspace = true, features = ["eip712", "macros"] }
proc-macro2.workspace = true
quote.workspace = true
syn.workspace = true

View File

@ -62,49 +62,40 @@
//! determine if there is a nested eip712 struct. However, this work is not yet complete.
#![deny(missing_docs, unsafe_code, rustdoc::broken_intra_doc_links)]
use ethers_core::{macros::ethers_core_crate, types::transaction::eip712};
use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use std::convert::TryFrom;
use syn::parse_macro_input;
use syn::{parse_macro_input, Result};
/// Derive macro for `Eip712`
#[proc_macro_derive(Eip712, attributes(eip712))]
pub fn eip_712_derive(input: TokenStream) -> TokenStream {
let ast = parse_macro_input!(input);
impl_eip_712_macro(&ast)
let input = parse_macro_input!(input);
match impl_eip_712_macro(&input) {
Ok(tokens) => tokens,
Err(e) => e.to_compile_error(),
}
.into()
}
// Main implementation macro, used to compute static values and define
// method for encoding the final eip712 payload;
fn impl_eip_712_macro(ast: &syn::DeriveInput) -> TokenStream {
fn impl_eip_712_macro(input: &syn::DeriveInput) -> Result<TokenStream2> {
// Primary type should match the type in the ethereum verifying contract;
let primary_type = &ast.ident;
let primary_type = &input.ident;
// Instantiate domain from parsed attributes
let domain = match eip712::EIP712Domain::try_from(ast) {
Ok(attributes) => attributes,
Err(e) => return TokenStream::from(e),
};
let domain = eip712::EIP712Domain::try_from(input)?;
let domain_separator = hex::encode(domain.separator());
//
let domain_str = match serde_json::to_string(&domain) {
Ok(s) => s,
Err(e) => {
return TokenStream::from(
syn::Error::new(ast.ident.span(), e.to_string()).to_compile_error(),
)
}
};
let domain_str = serde_json::to_string(&domain).unwrap();
// Must parse the AST at compile time.
let parsed_fields = match eip712::parse_fields(ast) {
Ok(fields) => fields,
Err(e) => return TokenStream::from(e),
};
let parsed_fields = eip712::parse_fields(input)?;
// Compute the type hash for the derived struct using the parsed fields from above.
let type_hash =
@ -113,7 +104,7 @@ fn impl_eip_712_macro(ast: &syn::DeriveInput) -> TokenStream {
// Use reference to ethers_core instead of directly using the crate itself.
let ethers_core = ethers_core_crate();
let implementation = quote! {
let tokens = quote! {
impl Eip712 for #primary_type {
type Error = #ethers_core::types::transaction::eip712::Eip712Error;
@ -168,5 +159,5 @@ fn impl_eip_712_macro(ast: &syn::DeriveInput) -> TokenStream {
}
};
implementation.into()
Ok(tokens)
}

View File

@ -7,7 +7,6 @@ use crate::{
use convert_case::{Case, Casing};
use core::convert::TryFrom;
use ethabi::encode;
use proc_macro2::TokenStream;
use serde::{Deserialize, Deserializer, Serialize};
use std::{
collections::{BTreeMap, HashSet},
@ -15,25 +14,25 @@ use std::{
iter::FromIterator,
};
use syn::{
parse::Error, spanned::Spanned as _, AttrStyle, Data, DeriveInput, Expr, Fields,
GenericArgument, Lit, NestedMeta, PathArguments, Type,
parse::Error, spanned::Spanned, Data, DeriveInput, Expr, Fields, GenericArgument, Lit, LitInt,
LitStr, PathArguments, Type,
};
/// Custom types for `TypedData`
pub type Types = BTreeMap<String, Vec<Eip712DomainType>>;
/// Pre-computed value of the following statement:
/// Pre-computed value of the following expression:
///
/// `ethers_core::utils::keccak256("EIP712Domain(string name,string version,uint256 chainId,address
/// `keccak256("EIP712Domain(string name,string version,uint256 chainId,address
/// verifyingContract)")`
pub const EIP712_DOMAIN_TYPE_HASH: [u8; 32] = [
139, 115, 195, 198, 155, 184, 254, 61, 81, 46, 204, 76, 247, 89, 204, 121, 35, 159, 123, 23,
155, 15, 250, 202, 169, 167, 93, 82, 43, 57, 64, 15,
];
/// Pre-computed value of the following statement:
/// Pre-computed value of the following expression:
///
/// `ethers_core::utils::keccak256("EIP712Domain(string name,string version,uint256 chainId,address
/// `keccak256("EIP712Domain(string name,string version,uint256 chainId,address
/// verifyingContract,bytes32 salt)")`
pub const EIP712_DOMAIN_TYPE_HASH_WITH_SALT: [u8; 32] = [
216, 124, 214, 239, 121, 212, 226, 185, 94, 21, 206, 138, 191, 115, 45, 181, 30, 199, 113, 241,
@ -247,190 +246,61 @@ impl<T: Eip712 + Clone> Eip712 for EIP712WithDomain<T> {
// Parse the AST of the struct to determine the domain attributes
impl TryFrom<&syn::DeriveInput> for EIP712Domain {
type Error = TokenStream;
type Error = Error;
fn try_from(input: &syn::DeriveInput) -> Result<EIP712Domain, Self::Error> {
const ERROR: &str = "unrecognized eip712 attribute";
const ALREADY_SPECIFIED: &str = "eip712 attribute already specified";
let mut domain = EIP712Domain::default();
let mut found_eip712_attribute = false;
for attr in input.attrs.iter() {
if !attr.path().is_ident("eip712") {
continue
}
'attribute_search: for attribute in input.attrs.iter() {
if let AttrStyle::Outer = attribute.style {
if let Ok(syn::Meta::List(meta)) = attribute.parse_meta() {
if meta.path.is_ident("eip712") {
found_eip712_attribute = true;
attr.parse_nested_meta(|meta| {
let ident = meta.path.get_ident().ok_or_else(|| meta.error(ERROR))?.to_string();
match ident.as_str() {
"name" if domain.name.is_none() => {
let litstr: LitStr = meta.input.parse()?;
domain.name = Some(litstr.value());
}
"name" => return Err(meta.error(ALREADY_SPECIFIED)),
for n in meta.nested.iter() {
if let NestedMeta::Meta(meta) = n {
match meta {
syn::Meta::NameValue(meta) => {
let ident = meta.path.get_ident().ok_or_else(|| {
Error::new(
meta.path.span(),
"unrecognized eip712 parameter",
)
.to_compile_error()
"version" if domain.version.is_none() => {
let litstr: LitStr = meta.input.parse()?;
domain.version = Some(litstr.value());
}
"version" => return Err(meta.error(ALREADY_SPECIFIED)),
"chain_id" if domain.chain_id.is_none() => {
let litint: LitInt = meta.input.parse()?;
let n: u64 = litint.base10_parse()?;
domain.chain_id = Some(n.into());
}
"chain_id" => return Err(meta.error(ALREADY_SPECIFIED)),
"verifying_contract" if domain.verifying_contract.is_none() => {
let litstr: LitStr = meta.input.parse()?;
let addr: Address =
litstr.value().parse().map_err(|e| Error::new(litstr.span(), e))?;
domain.verifying_contract = Some(addr);
}
"verifying_contract" => return Err(meta.error(ALREADY_SPECIFIED)),
"salt" if domain.salt.is_none() => {
let litstr: LitStr = meta.input.parse()?;
let hash = keccak256(litstr.value());
domain.salt = Some(hash);
}
"salt" => return Err(meta.error(ALREADY_SPECIFIED)),
_ => return Err(meta.error(ERROR)),
}
Ok(())
})?;
match ident.to_string().as_ref() {
"name" => match meta.lit {
syn::Lit::Str(ref lit_str) => {
if domain.name.is_some() {
return Err(Error::new(
meta.path.span(),
"domain name already specified",
)
.to_compile_error())
}
domain.name = Some(lit_str.value());
}
_ => {
return Err(Error::new(
meta.path.span(),
"domain name must be a string",
)
.to_compile_error())
}
},
"version" => match meta.lit {
syn::Lit::Str(ref lit_str) => {
if domain.version.is_some() {
return Err(Error::new(
meta.path.span(),
"domain version already specified",
)
.to_compile_error())
}
domain.version = Some(lit_str.value());
}
_ => {
return Err(Error::new(
meta.path.span(),
"domain version must be a string",
)
.to_compile_error())
}
},
"chain_id" => match meta.lit {
syn::Lit::Int(ref lit_int) => {
if domain.chain_id.is_some() {
return Err(Error::new(
meta.path.span(),
"domain chain_id already specified",
)
.to_compile_error())
}
domain.chain_id = Some(U256::from(
lit_int.base10_parse::<u64>().map_err(
|_| {
Error::new(
meta.path.span(),
"failed to parse chain id",
)
.to_compile_error()
},
)?,
));
}
_ => {
return Err(Error::new(
meta.path.span(),
"domain chain_id must be a positive integer",
)
.to_compile_error());
}
},
"verifying_contract" => match meta.lit {
syn::Lit::Str(ref lit_str) => {
if domain.verifying_contract.is_some() {
return Err(Error::new(
meta.path.span(),
"domain verifying_contract already specified",
)
.to_compile_error());
}
domain.verifying_contract = Some(lit_str.value().parse().map_err(|_| {
Error::new(
meta.path.span(),
"failed to parse verifying contract into Address",
)
.to_compile_error()
})?);
}
_ => {
return Err(Error::new(
meta.path.span(),
"domain verifying_contract must be a string",
)
.to_compile_error());
}
},
"salt" => match meta.lit {
syn::Lit::Str(ref lit_str) => {
if domain.salt.is_some() {
return Err(Error::new(
meta.path.span(),
"domain salt already specified",
)
.to_compile_error())
}
// keccak256(<string>) to compute bytes32
// encoded domain salt
let salt = keccak256(lit_str.value());
domain.salt = Some(salt);
}
_ => {
return Err(Error::new(
meta.path.span(),
"domain salt must be a string",
)
.to_compile_error())
}
},
_ => {
return Err(Error::new(
meta.path.span(),
"unrecognized eip712 parameter; must be one of 'name', 'version', 'chain_id', or 'verifying_contract'",
)
.to_compile_error());
}
}
}
syn::Meta::Path(path) => {
return Err(Error::new(
path.span(),
"unrecognized eip712 parameter",
)
.to_compile_error())
}
syn::Meta::List(meta) => {
return Err(Error::new(
meta.path.span(),
"unrecognized eip712 parameter",
)
.to_compile_error())
}
}
}
}
}
break 'attribute_search
}
}
}
if !found_eip712_attribute {
return Err(Error::new_spanned(
input,
"missing required derive attribute: '#[eip712( ... )]'".to_string(),
)
.to_compile_error())
}
Ok(domain)
@ -442,36 +312,35 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain {
/// Typed data is a JSON object containing type information, domain separator parameters and the
/// message object which has the following schema
///
/// ```js
/// ```json
/// {
// type: 'object',
// properties: {
// types: {
// type: 'object',
// properties: {
// EIP712Domain: {type: 'array'},
// },
// additionalProperties: {
// type: 'array',
// items: {
// type: 'object',
// properties: {
// name: {type: 'string'},
// type: {type: 'string'}
// },
// required: ['name', 'type']
// }
// },
// required: ['EIP712Domain']
// },
// primaryType: {type: 'string'},
// domain: {type: 'object'},
// message: {type: 'object'}
// },
// required: ['types', 'primaryType', 'domain', 'message']
// }
/// "type": "object",
/// "properties": {
/// "types": {
/// "type": "object",
/// "properties": {
/// "EIP712Domain": { "type": "array" }
/// },
/// "additionalProperties": {
/// "type": "array",
/// "items": {
/// "type": "object",
/// "properties": {
/// "name": { "type": "string" },
/// "type": { "type": "string" }
/// },
/// "required": ["name", "type"]
/// }
/// },
/// "required": ["EIP712Domain"]
/// },
/// "primaryType": { "type": "string" },
/// "domain": { "type": "object" },
/// "message": { "type": "object" }
/// },
/// "required": ["types", "primaryType", "domain", "message"]
/// }
/// ```
///
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
#[serde(deny_unknown_fields)]
pub struct TypedData {
@ -775,7 +644,7 @@ pub fn encode_field(
/// Parse the eth abi parameter type based on the syntax type;
/// this method is copied from <https://github.com/gakonst/ethers-rs/blob/master/ethers-contract/ethers-contract-derive/src/lib.rs#L600>
/// with additional modifications for finding byte arrays
pub fn find_parameter_type(ty: &Type) -> Result<ParamType, TokenStream> {
pub fn find_parameter_type(ty: &Type) -> Result<ParamType, Error> {
match ty {
Type::Array(ty) => {
let param = find_parameter_type(ty.elem.as_ref())?;
@ -790,8 +659,7 @@ pub fn find_parameter_type(ty: &Type) -> Result<ParamType, TokenStream> {
}
}
}
Err(Error::new(ty.span(), "Failed to derive proper ABI from array field")
.to_compile_error())
Err(Error::new(ty.span(), "Failed to derive proper ABI from array field"))
}
Type::Path(ty) => {
if let Some(ident) = ty.path.get_ident() {
@ -810,7 +678,6 @@ pub fn find_parameter_type(ty: &Type) -> Result<ParamType, TokenStream> {
ty.span(),
format!("Failed to derive proper ABI from field: {s})"),
)
.to_compile_error()
}),
}
}
@ -834,15 +701,13 @@ pub fn find_parameter_type(ty: &Type) -> Result<ParamType, TokenStream> {
}
}
Err(Error::new(ty.span(), "Failed to derive proper ABI from fields").to_compile_error())
Err(Error::new(ty.span(), "Failed to derive proper ABI from fields"))
}
Type::Tuple(ty) => {
let params = ty.elems.iter().map(find_parameter_type).collect::<Result<Vec<_>, _>>()?;
Ok(ParamType::Tuple(params))
}
_ => {
Err(Error::new(ty.span(), "Failed to derive proper ABI from fields").to_compile_error())
}
_ => Err(Error::new(ty.span(), "Failed to derive proper ABI from fields")),
}
}
@ -857,41 +722,33 @@ fn parse_int_param_type(s: &str) -> Option<ParamType> {
}
}
/// Return HashMap of the field name and the field type;
pub fn parse_fields(ast: &DeriveInput) -> Result<Vec<(String, ParamType)>, TokenStream> {
/// Return HashMap of the field name and the field type
pub fn parse_fields(input: &DeriveInput) -> Result<Vec<(String, ParamType)>, Error> {
let mut fields = Vec::new();
let data = match &ast.data {
let data = match &input.data {
Data::Struct(s) => s,
_ => {
return Err(Error::new(
ast.span(),
"invalid data type. can only derive Eip712 for a struct",
)
.to_compile_error())
Data::Enum(e) => {
return Err(Error::new(e.enum_token.span, "Eip712 is not derivable for enums"))
}
Data::Union(u) => {
return Err(Error::new(u.union_token.span, "Eip712 is not derivable for unions"))
}
};
let named_fields = match &data.fields {
Fields::Named(name) => name,
_ => {
return Err(Error::new(ast.span(), "unnamed fields are not supported").to_compile_error())
}
_ => return Err(Error::new(input.span(), "unnamed fields are not supported")),
};
for f in named_fields.named.iter() {
let field_name =
f.ident.clone().map(|i| i.to_string().to_case(Case::Camel)).ok_or_else(|| {
Error::new(named_fields.span(), "fields must be named").to_compile_error()
})?;
let field_name = f.ident.as_ref().unwrap().to_string().to_case(Case::Camel);
let field_type =
match f.attrs.iter().find(|a| a.path.segments.iter().any(|s| s.ident == "eip712")) {
match f.attrs.iter().find(|a| a.path().segments.iter().any(|s| s.ident == "eip712")) {
// Found nested Eip712 Struct
// TODO: Implement custom
Some(a) => {
return Err(Error::new(a.span(), "nested Eip712 struct are not yet supported")
.to_compile_error())
return Err(Error::new(a.span(), "nested Eip712 struct are not yet supported"))
}
// Not a nested eip712 struct, return the field param type;
None => find_parameter_type(&f.ty)?,