diff --git a/ethabi/src/decoder.rs b/ethabi/src/decoder.rs index cc4414708..bb25572e7 100644 --- a/ethabi/src/decoder.rs +++ b/ethabi/src/decoder.rs @@ -240,7 +240,7 @@ fn decode_param(param: &ParamType, data: &[u8], offset: usize, validate: bool) - let len = t.len(); let mut tokens = Vec::with_capacity(len); for param in t { - let res = decode_param(param, tail, new_offset, validate)?; + let res = decode_param(¶m.kind, tail, new_offset, validate)?; new_offset = res.new_offset; tokens.push(res.token); } @@ -300,9 +300,11 @@ mod tests { let uint = Token::Uint([0x11u8; 32].into()); let tuple = Token::Tuple(vec![address1, address2, uint]); let expected = vec![tuple]; - let decoded = - decode(&[ParamType::Tuple(vec![ParamType::Address, ParamType::Address, ParamType::Uint(32)])], &encoded) - .unwrap(); + let decoded = decode( + &[ParamType::Tuple(vec![ParamType::Address.into(), ParamType::Address.into(), ParamType::Uint(32).into()])], + &encoded, + ) + .unwrap(); assert_eq!(decoded, expected); } @@ -322,7 +324,8 @@ mod tests { let string1 = Token::String("gavofyork".to_owned()); let string2 = Token::String("gavofyork".to_owned()); let tuple = Token::Tuple(vec![string1, string2]); - let decoded = decode(&[ParamType::Tuple(vec![ParamType::String, ParamType::String])], &encoded).unwrap(); + let decoded = + decode(&[ParamType::Tuple(vec![ParamType::String.into(), ParamType::String.into()])], &encoded).unwrap(); let expected = vec![tuple]; assert_eq!(decoded, expected); } @@ -368,14 +371,15 @@ mod tests { let expected = vec![outer_tuple]; let decoded = decode( &[ParamType::Tuple(vec![ - ParamType::String, - ParamType::Bool, - ParamType::String, + ParamType::String.into(), + ParamType::Bool.into(), + ParamType::String.into(), ParamType::Tuple(vec![ - ParamType::String, - ParamType::String, - ParamType::Tuple(vec![ParamType::String, ParamType::String]), - ]), + ParamType::String.into(), + ParamType::String.into(), + ParamType::Tuple(vec![ParamType::String.into(), ParamType::String.into()]).into(), + ]) + .into(), ])], &encoded, ) @@ -403,7 +407,12 @@ mod tests { let tuple = Token::Tuple(vec![uint, string, address1, address2]); let expected = vec![tuple]; let decoded = decode( - &[ParamType::Tuple(vec![ParamType::Uint(32), ParamType::String, ParamType::Address, ParamType::Address])], + &[ParamType::Tuple(vec![ + ParamType::Uint(32).into(), + ParamType::String.into(), + ParamType::Address.into(), + ParamType::Address.into(), + ])], &encoded, ) .unwrap(); @@ -440,7 +449,7 @@ mod tests { let decoded = decode( &[ ParamType::Address, - ParamType::Tuple(vec![ParamType::Bool, ParamType::String, ParamType::String]), + ParamType::Tuple(vec![ParamType::Bool.into(), ParamType::String.into(), ParamType::String.into()]), ParamType::Address, ParamType::Address, ParamType::Bool, @@ -475,7 +484,7 @@ mod tests { let decoded = decode( &[ ParamType::Address, - ParamType::Tuple(vec![ParamType::Address, ParamType::Bool, ParamType::Bool]), + ParamType::Tuple(vec![ParamType::Address.into(), ParamType::Bool.into(), ParamType::Bool.into()]), ParamType::Address, ParamType::Address, ], @@ -654,14 +663,15 @@ ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff inputs: vec![ Param { name: "c".to_string(), - kind: Array(Box::new(Tuple(vec![Uint(256), Uint(256)]))), + kind: Array(Box::new(Tuple(vec![Uint(256).into(), Uint(256).into()]))), internal_type: None, }, Param { name: "d".to_string(), kind: Array(Box::new(Tuple(vec![ - Uint(256), - Array(Box::new(Tuple(vec![Uint(256), Array(Box::new(ParamType::String))]))), + Uint(256).into(), + Array(Box::new(Tuple(vec![Uint(256).into(), Array(Box::new(ParamType::String)).into()]))) + .into(), ]))), internal_type: None, }, diff --git a/ethabi/src/event.rs b/ethabi/src/event.rs index 3df342bf1..571e52ade 100644 --- a/ethabi/src/event.rs +++ b/ethabi/src/event.rs @@ -297,7 +297,7 @@ mod tests { inputs: vec![ EventParam { name: "tuple".into(), - kind: ParamType::Tuple(vec![ParamType::Address, ParamType::Address]), + kind: ParamType::Tuple(vec![ParamType::Address.into(), ParamType::Address.into()]), indexed: false, }, EventParam { name: "addr".into(), kind: ParamType::Address, indexed: true }, diff --git a/ethabi/src/event_param.rs b/ethabi/src/event_param.rs index b41b3f12d..abbbbebb5 100644 --- a/ethabi/src/event_param.rs +++ b/ethabi/src/event_param.rs @@ -169,7 +169,10 @@ mod tests { deserialized, EventParam { name: "foo".to_owned(), - kind: ParamType::Tuple(vec![ParamType::Uint(48), ParamType::Tuple(vec![ParamType::Address])]), + kind: ParamType::Tuple(vec![ + ParamType::Uint(48).into(), + ParamType::Tuple(vec![ParamType::Address.into()]).into() + ]), indexed: true, } ); @@ -225,16 +228,25 @@ mod tests { EventParam { name: "LogTaskSubmitted".to_owned(), kind: ParamType::Tuple(vec![ - ParamType::Uint(256), - ParamType::Address, - ParamType::Tuple(vec![ParamType::Address, ParamType::Address]), - ParamType::Uint(256), + ParamType::Uint(256).into(), + ParamType::Address.into(), + ParamType::Tuple(vec![ParamType::Address.into(), ParamType::Address.into()]).into(), + ParamType::Uint(256).into(), ParamType::Array(Box::new(ParamType::Tuple(vec![ - ParamType::Array(Box::new(ParamType::Tuple(vec![ParamType::Address, ParamType::Bytes,]))), - ParamType::Array(Box::new(ParamType::Tuple(vec![ParamType::Address, ParamType::Uint(256)]))), - ParamType::Uint(256), - ]))), - ParamType::Uint(256), + ParamType::Array(Box::new(ParamType::Tuple(vec![ + ParamType::Address.into(), + ParamType::Bytes.into(), + ]))) + .into(), + ParamType::Array(Box::new(ParamType::Tuple(vec![ + ParamType::Address.into(), + ParamType::Uint(256).into() + ]))) + .into(), + ParamType::Uint(256).into(), + ]))) + .into(), + ParamType::Uint(256).into(), ]), indexed: false, } diff --git a/ethabi/src/lib.rs b/ethabi/src/lib.rs index d8e38fe06..abdb98fe1 100644 --- a/ethabi/src/lib.rs +++ b/ethabi/src/lib.rs @@ -48,7 +48,6 @@ pub mod param_type; mod signature; mod state_mutability; pub mod token; -#[cfg(feature = "serde")] mod tuple_param; mod util; @@ -57,8 +56,6 @@ mod tests; pub use ethereum_types; -#[cfg(feature = "serde")] -pub use crate::tuple_param::TupleParam; pub use crate::{ constructor::Constructor, contract::{Contract, Events, Functions}, @@ -76,6 +73,7 @@ pub use crate::{ signature::{long_signature, short_signature}, state_mutability::StateMutability, token::Token, + tuple_param::TupleParam, }; /// ABI word. diff --git a/ethabi/src/operation.rs b/ethabi/src/operation.rs index 4e8a9d4ac..a6939da5a 100644 --- a/ethabi/src/operation.rs +++ b/ethabi/src/operation.rs @@ -40,7 +40,7 @@ mod tests { use super::Operation; #[cfg(not(feature = "std"))] use crate::no_std_prelude::*; - use crate::{tests::assert_ser_de, Event, EventParam, Function, Param, ParamType, StateMutability}; + use crate::{tests::assert_ser_de, Event, EventParam, Function, Param, ParamType, StateMutability, TupleParam}; #[test] fn operation() { @@ -119,9 +119,21 @@ mod tests { EventParam { name: "b".to_owned(), kind: ParamType::Array(Box::new(ParamType::Tuple(vec![ - ParamType::Address, - ParamType::Uint(256), - ParamType::Bytes + TupleParam { + name: Some("to".into()), + kind: ParamType::Address, + internal_type: Some("address".into()) + }, + TupleParam { + name: Some("value".into()), + kind: ParamType::Uint(256), + internal_type: Some("uint256".into()) + }, + TupleParam { + name: Some("data".into()), + kind: ParamType::Bytes, + internal_type: Some("bytes".into()) + } ]))), indexed: false }, diff --git a/ethabi/src/param.rs b/ethabi/src/param.rs index 5e619835d..a0e1672e7 100644 --- a/ethabi/src/param.rs +++ b/ethabi/src/param.rs @@ -123,7 +123,7 @@ impl Serialize for Param { } #[cfg(feature = "serde")] -pub(crate) fn inner_tuple_mut(mut param: &mut ParamType) -> Option<&mut Vec> { +pub(crate) fn inner_tuple_mut(mut param: &mut ParamType) -> Option<&mut Vec> { loop { match param { ParamType::Array(inner) => param = inner.as_mut(), @@ -135,7 +135,7 @@ pub(crate) fn inner_tuple_mut(mut param: &mut ParamType) -> Option<&mut Vec Option<&Vec> { +pub(crate) fn inner_tuple(mut param: &ParamType) -> Option<&Vec> { loop { match param { ParamType::Array(inner) => param = inner.as_ref(), @@ -153,13 +153,13 @@ pub(crate) fn set_tuple_components( ) -> Result<(), Error> { if let Some(inner_tuple_mut) = inner_tuple_mut(kind) { let tuple_params = components.ok_or_else(|| Error::missing_field("components"))?; - inner_tuple_mut.extend(tuple_params.into_iter().map(|param| param.kind)) + inner_tuple_mut.extend(tuple_params.into_iter()) } Ok(()) } #[cfg(feature = "serde")] -pub(crate) struct SerializeableParamVec<'a>(pub(crate) &'a [ParamType]); +pub(crate) struct SerializeableParamVec<'a>(pub(crate) &'a [TupleParam]); #[cfg(feature = "serde")] impl Serialize for SerializeableParamVec<'_> { @@ -176,7 +176,7 @@ impl Serialize for SerializeableParamVec<'_> { } #[cfg(feature = "serde")] -pub(crate) struct SerializeableParam<'a>(pub(crate) &'a ParamType); +pub(crate) struct SerializeableParam<'a>(pub(crate) &'a TupleParam); #[cfg(feature = "serde")] impl Serialize for SerializeableParam<'_> { @@ -185,8 +185,14 @@ impl Serialize for SerializeableParam<'_> { S: Serializer, { let mut map = serializer.serialize_map(None)?; - map.serialize_entry("type", &Writer::write_for_abi(self.0, false))?; - if let Some(inner_tuple) = inner_tuple(self.0) { + map.serialize_entry("type", &Writer::write_for_abi(&self.0.kind, false))?; + if let Some(ref name) = self.0.name { + map.serialize_entry("name", &name)?; + } + if let Some(ref internal_type) = self.0.internal_type { + map.serialize_entry("internalType", &internal_type)?; + } + if let Some(inner_tuple) = inner_tuple(&self.0.kind) { map.serialize_key("components")?; map.serialize_value(&SerializeableParamVec(inner_tuple))?; } @@ -200,7 +206,7 @@ mod tests { use crate::no_std_prelude::*; use crate::{ tests::{assert_json_eq, assert_ser_de}, - Param, ParamType, + Param, ParamType, TupleParam, }; #[test] @@ -265,7 +271,10 @@ mod tests { deserialized, Param { name: "foo".to_owned(), - kind: ParamType::Tuple(vec![ParamType::Uint(48), ParamType::Tuple(vec![ParamType::Address])]), + kind: ParamType::Tuple(vec![ + ParamType::Uint(48).into(), + ParamType::Tuple(vec![ParamType::Address.into()]).into() + ]), internal_type: None } ); @@ -300,7 +309,10 @@ mod tests { deserialized, Param { name: "foo".to_owned(), - kind: ParamType::Tuple(vec![ParamType::Uint(48), ParamType::Tuple(vec![ParamType::Address])]), + kind: ParamType::Tuple(vec![ + ParamType::Uint(48).into(), + ParamType::Tuple(vec![ParamType::Address.into()]).into() + ]), internal_type: Some("struct Pairing.G1Point[]".to_string()) } ); @@ -337,9 +349,20 @@ mod tests { deserialized, Param { name: "foo".to_owned(), - kind: ParamType::Tuple(vec![ParamType::Uint(48), ParamType::Tuple(vec![ParamType::Address])]), + kind: ParamType::Tuple(vec![ + TupleParam { name: Some("amount".into()), kind: ParamType::Uint(48), internal_type: None }, + TupleParam { + name: Some("things".into()), + kind: ParamType::Tuple(vec![TupleParam { + name: Some("baseTupleParam".into()), + kind: ParamType::Address, + internal_type: None + }]), + internal_type: None + } + ]), internal_type: None - } + }, ); assert_ser_de(&deserialized); @@ -370,9 +393,9 @@ mod tests { Param { name: "foo".to_owned(), kind: ParamType::Array(Box::new(ParamType::Tuple(vec![ - ParamType::Uint(48), - ParamType::Address, - ParamType::Address + ParamType::Uint(48).into(), + ParamType::Address.into(), + ParamType::Address.into() ]))), internal_type: None } @@ -402,8 +425,8 @@ mod tests { Param { name: "foo".to_owned(), kind: ParamType::Array(Box::new(ParamType::Array(Box::new(ParamType::Tuple(vec![ - ParamType::Uint(8), - ParamType::Uint(16), + ParamType::Uint(8).into(), + ParamType::Uint(16).into(), ]))))), internal_type: None } @@ -437,7 +460,11 @@ mod tests { Param { name: "foo".to_owned(), kind: ParamType::FixedArray( - Box::new(ParamType::Tuple(vec![ParamType::Uint(48), ParamType::Address, ParamType::Address])), + Box::new(ParamType::Tuple(vec![ + ParamType::Uint(48).into(), + ParamType::Address.into(), + ParamType::Address.into() + ])), 2 ), internal_type: None @@ -479,8 +506,8 @@ mod tests { Param { name: "foo".to_owned(), kind: ParamType::Tuple(vec![ - ParamType::Array(Box::new(ParamType::Tuple(vec![ParamType::Address]))), - ParamType::FixedArray(Box::new(ParamType::Tuple(vec![ParamType::Address])), 42,) + ParamType::Array(Box::new(ParamType::Tuple(vec![ParamType::Address.into()]))).into(), + ParamType::FixedArray(Box::new(ParamType::Tuple(vec![ParamType::Address.into()])), 42,).into(), ]), internal_type: None } diff --git a/ethabi/src/param_type/param_type.rs b/ethabi/src/param_type/param_type.rs index 31edb9429..fe389c5d8 100644 --- a/ethabi/src/param_type/param_type.rs +++ b/ethabi/src/param_type/param_type.rs @@ -13,6 +13,7 @@ use core::fmt; use super::Writer; #[cfg(not(feature = "std"))] use crate::no_std_prelude::*; +use crate::TupleParam; /// Function and event param types. #[derive(Debug, Clone, PartialEq)] @@ -36,7 +37,7 @@ pub enum ParamType { /// Array with fixed size. FixedArray(Box, usize), /// Tuple containing different types - Tuple(Vec), + Tuple(Vec), } impl fmt::Display for ParamType { @@ -62,7 +63,7 @@ impl ParamType { match self { ParamType::Bytes | ParamType::String | ParamType::Array(_) => true, ParamType::FixedArray(elem_type, _) => elem_type.is_dynamic(), - ParamType::Tuple(params) => params.iter().any(|param| param.is_dynamic()), + ParamType::Tuple(params) => params.iter().any(|param| param.kind.is_dynamic()), _ => false, } } diff --git a/ethabi/src/param_type/reader.rs b/ethabi/src/param_type/reader.rs index a81c974dd..7af78a5d6 100644 --- a/ethabi/src/param_type/reader.rs +++ b/ethabi/src/param_type/reader.rs @@ -8,7 +8,7 @@ #[cfg(not(feature = "std"))] use crate::no_std_prelude::*; -use crate::{Error, ParamType}; +use crate::{Error, ParamType, TupleParam}; /// Used to convert param type represented as a string to rust structure. pub struct Reader; @@ -60,7 +60,7 @@ impl Reader { // check for trailing brackets that indicate array of tuples let sub = &name[last_item..pos]; let subtype = Reader::read(sub)?; - subtypes.push(subtype); + subtypes.push(TupleParam { name: None, kind: subtype, internal_type: None }); last_item = pos + 1; } // If the item is in a sublevel of the tuple @@ -83,10 +83,14 @@ impl Reader { if nested > 1 { let mut subtuple = core::mem::take(&mut subtuples[(nested - 2) as usize]); - subtuple.push(subtype); - subtypes.push(ParamType::Tuple(subtuple)); + subtuple.push(TupleParam { name: None, kind: subtype, internal_type: None }); + subtypes.push(TupleParam { + name: None, + kind: ParamType::Tuple(subtuple), + internal_type: None, + }); } else { - subtypes.push(subtype); + subtypes.push(TupleParam { name: None, kind: subtype, internal_type: None }); } last_item = pos + 1; } @@ -101,7 +105,7 @@ impl Reader { else if nested == 1 { let sub = &name[last_item..pos]; let subtype = Reader::read(sub)?; - subtypes.push(subtype); + subtypes.push(TupleParam { name: None, kind: subtype, internal_type: None }); last_item = pos + 1; } // If the item is in a sublevel of the tuple @@ -109,7 +113,11 @@ impl Reader { else if nested > 1 { let sub = &name[last_item..pos]; let subtype = Reader::read(sub)?; - subtuples[(nested - 2) as usize].push(subtype); + subtuples[(nested - 2) as usize].push(TupleParam { + name: None, + kind: subtype, + internal_type: None, + }); last_item = pos + 1; } } @@ -228,11 +236,14 @@ mod tests { fn test_read_struct_param() { assert_eq!( Reader::read("(address,bool)").unwrap(), - ParamType::Tuple(vec![ParamType::Address, ParamType::Bool]) + ParamType::Tuple(vec![ParamType::Address.into(), ParamType::Bool.into()]) ); assert_eq!( Reader::read("(bool[3],uint256)").unwrap(), - ParamType::Tuple(vec![ParamType::FixedArray(Box::new(ParamType::Bool), 3), ParamType::Uint(256)]) + ParamType::Tuple(vec![ + ParamType::FixedArray(Box::new(ParamType::Bool), 3).into(), + ParamType::Uint(256).into() + ]) ); } @@ -241,9 +252,9 @@ mod tests { assert_eq!( Reader::read("(address,bool,(bool,uint256))").unwrap(), ParamType::Tuple(vec![ - ParamType::Address, - ParamType::Bool, - ParamType::Tuple(vec![ParamType::Bool, ParamType::Uint(256)]) + ParamType::Address.into(), + ParamType::Bool.into(), + ParamType::Tuple(vec![ParamType::Bool.into(), ParamType::Uint(256).into()]).into() ]) ); } @@ -253,14 +264,15 @@ mod tests { assert_eq!( Reader::read("(address,bool,(bool,uint256,(bool,uint256)),(bool,uint256))").unwrap(), ParamType::Tuple(vec![ - ParamType::Address, - ParamType::Bool, + ParamType::Address.into(), + ParamType::Bool.into(), ParamType::Tuple(vec![ - ParamType::Bool, - ParamType::Uint(256), - ParamType::Tuple(vec![ParamType::Bool, ParamType::Uint(256)]) - ]), - ParamType::Tuple(vec![ParamType::Bool, ParamType::Uint(256)]) + ParamType::Bool.into(), + ParamType::Uint(256).into(), + ParamType::Tuple(vec![ParamType::Bool.into(), ParamType::Uint(256).into()]).into() + ]) + .into(), + ParamType::Tuple(vec![ParamType::Bool.into(), ParamType::Uint(256).into()]).into() ]) ); } @@ -269,7 +281,10 @@ mod tests { fn test_read_nested_tuple_array_param() { assert_eq!( Reader::read("(uint256,bytes32)[]").unwrap(), - ParamType::Array(Box::new(ParamType::Tuple(vec![ParamType::Uint(256), ParamType::FixedBytes(32)]))) + ParamType::Array(Box::new(ParamType::Tuple(vec![ + ParamType::Uint(256).into(), + ParamType::FixedBytes(32).into() + ]))) ) } @@ -280,8 +295,12 @@ mod tests { let read = Reader::read(abi).unwrap(); let param = ParamType::Tuple(vec![ - ParamType::Array(Box::new(ParamType::Tuple(vec![ParamType::Uint(256), ParamType::FixedBytes(32)]))), - ParamType::Address, + ParamType::Array(Box::new(ParamType::Tuple(vec![ + ParamType::Uint(256).into(), + ParamType::FixedBytes(32).into(), + ]))) + .into(), + ParamType::Address.into(), ]); assert_eq!(read, param); diff --git a/ethabi/src/param_type/writer.rs b/ethabi/src/param_type/writer.rs index 14a076845..2954cd2b4 100644 --- a/ethabi/src/param_type/writer.rs +++ b/ethabi/src/param_type/writer.rs @@ -41,7 +41,7 @@ impl Writer { if serialize_tuple_contents { let formatted = params .iter() - .map(|t| Writer::write_for_abi(t, serialize_tuple_contents)) + .map(|t| Writer::write_for_abi(&t.kind, serialize_tuple_contents)) .collect::>() .join(","); format!("({formatted})") @@ -77,8 +77,12 @@ mod tests { ); assert_eq!( Writer::write(&ParamType::Array(Box::new(ParamType::Tuple(vec![ - ParamType::Array(Box::new(ParamType::Tuple(vec![ParamType::Int(256), ParamType::Uint(256)]))), - ParamType::FixedBytes(32), + ParamType::Array(Box::new(ParamType::Tuple(vec![ + ParamType::Int(256).into(), + ParamType::Uint(256).into() + ]))) + .into(), + ParamType::FixedBytes(32).into(), ])))), "((int256,uint256)[],bytes32)[]".to_owned() ); @@ -86,8 +90,8 @@ mod tests { assert_eq!( Writer::write_for_abi( &ParamType::Array(Box::new(ParamType::Tuple(vec![ - ParamType::Array(Box::new(ParamType::Int(256))), - ParamType::FixedBytes(32), + ParamType::Array(Box::new(ParamType::Int(256))).into(), + ParamType::FixedBytes(32).into(), ]))), false ), diff --git a/ethabi/src/tests.rs b/ethabi/src/tests.rs index 73726e548..a0b00c5ae 100644 --- a/ethabi/src/tests.rs +++ b/ethabi/src/tests.rs @@ -565,10 +565,10 @@ test_encode_decode! { ParamType::Tuple(vec![ ParamType::Array(Box::new(ParamType::Tuple( vec![ - ParamType::Address, - ParamType::Uint(256) + ParamType::Address.into(), + ParamType::Uint(256).into(), ] - ))) + ))).into() ]) ], tokens: { diff --git a/ethabi/src/token/mod.rs b/ethabi/src/token/mod.rs index 3df155fa4..be80ed256 100644 --- a/ethabi/src/token/mod.rs +++ b/ethabi/src/token/mod.rs @@ -48,7 +48,7 @@ pub trait Tokenizer { ParamType::Int(_) => Self::tokenize_int(value).map(Into::into).map(Token::Int), ParamType::Array(ref p) => Self::tokenize_array(value, p).map(Token::Array), ParamType::FixedArray(ref p, len) => Self::tokenize_fixed_array(value, p, len).map(Token::FixedArray), - ParamType::Tuple(ref p) => Self::tokenize_struct(value, p).map(Token::Tuple), + ParamType::Tuple(ref p) => Self::tokenize_struct(value, p.iter().map(|t| &t.kind)).map(Token::Tuple), } } @@ -62,7 +62,7 @@ pub trait Tokenizer { } /// Tried to parse a struct as a vector of tokens - fn tokenize_struct(value: &str, param: &[ParamType]) -> Result, Error> { + fn tokenize_struct<'a, I: IntoIterator>(value: &str, param: I) -> Result, Error> { if !value.starts_with('(') || !value.ends_with(')') { return Err(Error::InvalidData); } @@ -80,7 +80,7 @@ pub trait Tokenizer { let mut array_item_start = 1; let mut last_is_array = false; - let mut params = param.iter(); + let mut params = param.into_iter(); for (pos, ch) in value.chars().enumerate() { match ch { '[' if !ignore => { @@ -294,8 +294,9 @@ mod test { LenientTokenizer::tokenize_array( "[([(true)],[(false,true)])]", &ParamType::Tuple(vec![ - ParamType::Array(Box::new(ParamType::Tuple(vec![ParamType::Bool]))), - ParamType::Array(Box::new(ParamType::Tuple(vec![ParamType::Bool, ParamType::Bool]))), + ParamType::Array(Box::new(ParamType::Tuple(vec![ParamType::Bool.into()]))).into(), + ParamType::Array(Box::new(ParamType::Tuple(vec![ParamType::Bool.into(), ParamType::Bool.into()]))) + .into(), ]), ) .unwrap(), @@ -309,8 +310,8 @@ mod test { LenientTokenizer::tokenize_struct( "([(true)],[(false,true)])", &[ - ParamType::Array(Box::new(ParamType::Tuple(vec![ParamType::Bool]))), - ParamType::Array(Box::new(ParamType::Tuple(vec![ParamType::Bool, ParamType::Bool]))), + ParamType::Array(Box::new(ParamType::Tuple(vec![ParamType::Bool.into()]))), + ParamType::Array(Box::new(ParamType::Tuple(vec![ParamType::Bool.into(), ParamType::Bool.into()]))), ] ) .unwrap(), @@ -326,7 +327,10 @@ mod test { assert_eq!( LenientTokenizer::tokenize_struct( "([(5c9d55b78febcc2061715ba4f57ecf8ea2711f2c)],2)", - &[ParamType::Array(Box::new(ParamType::Tuple(vec![ParamType::Address,],)),), ParamType::Uint(256,),] + &[ + ParamType::Array(Box::new(ParamType::Tuple(vec![ParamType::Address.into(),],)),), + ParamType::Uint(256,), + ] ) .unwrap(), vec![ diff --git a/ethabi/src/token/token.rs b/ethabi/src/token/token.rs index 2010db954..7b78fe3cc 100644 --- a/ethabi/src/token/token.rs +++ b/ethabi/src/token/token.rs @@ -133,7 +133,7 @@ impl Token { } Token::Tuple(ref tokens) => { if let ParamType::Tuple(ref param_type) = *param_type { - tokens.iter().enumerate().all(|(i, t)| t.type_check(¶m_type[i])) + tokens.iter().enumerate().all(|(i, t)| t.type_check(¶m_type[i].kind)) } else { false } diff --git a/ethabi/src/tuple_param.rs b/ethabi/src/tuple_param.rs index a85b9aa79..30289a4a7 100644 --- a/ethabi/src/tuple_param.rs +++ b/ethabi/src/tuple_param.rs @@ -12,6 +12,7 @@ use crate::no_std_prelude::*; use crate::{param_type::Writer, ParamType}; use core::fmt; +#[cfg(feature = "serde")] use serde::{ de::{Error, MapAccess, Visitor}, ser::SerializeMap, @@ -31,6 +32,13 @@ pub struct TupleParam { pub internal_type: Option, } +impl From for TupleParam { + fn from(value: ParamType) -> Self { + Self { name: None, kind: value, internal_type: None } + } +} + +#[cfg(feature = "serde")] impl<'a> Deserialize<'a> for TupleParam { fn deserialize(deserializer: D) -> Result where @@ -40,8 +48,10 @@ impl<'a> Deserialize<'a> for TupleParam { } } +#[cfg(feature = "serde")] struct TupleParamVisitor; +#[cfg(feature = "serde")] impl<'a> Visitor<'a> for TupleParamVisitor { type Value = TupleParam; @@ -95,6 +105,7 @@ impl<'a> Visitor<'a> for TupleParamVisitor { } } +#[cfg(feature = "serde")] impl Serialize for TupleParam { fn serialize(&self, serializer: S) -> Result where @@ -202,7 +213,10 @@ mod tests { deserialized, TupleParam { name: None, - kind: ParamType::Tuple(vec![ParamType::Uint(48), ParamType::Tuple(vec![ParamType::Address])]), + kind: ParamType::Tuple(vec![ + ParamType::Uint(48).into(), + ParamType::Tuple(vec![ParamType::Address.into()]).into() + ]), internal_type: None } ); @@ -238,7 +252,18 @@ mod tests { deserialized, TupleParam { name: None, - kind: ParamType::Tuple(vec![ParamType::Uint(48), ParamType::Tuple(vec![ParamType::Address])]), + kind: ParamType::Tuple(vec![ + TupleParam { name: Some("amount".into()), kind: ParamType::Uint(48), internal_type: None }, + TupleParam { + name: Some("things".into()), + kind: ParamType::Tuple(vec![TupleParam { + name: Some("baseTupleParam".into()), + kind: ParamType::Address, + internal_type: None + }]), + internal_type: None + } + ]), internal_type: None } ); @@ -270,9 +295,9 @@ mod tests { TupleParam { name: None, kind: ParamType::Array(Box::new(ParamType::Tuple(vec![ - ParamType::Uint(48), - ParamType::Address, - ParamType::Address + ParamType::Uint(48).into(), + ParamType::Address.into(), + ParamType::Address.into() ]))), internal_type: None } @@ -301,8 +326,8 @@ mod tests { TupleParam { name: None, kind: ParamType::Array(Box::new(ParamType::Array(Box::new(ParamType::Tuple(vec![ - ParamType::Uint(8), - ParamType::Uint(16), + ParamType::Uint(8).into(), + ParamType::Uint(16).into(), ]))))), internal_type: None } @@ -335,7 +360,11 @@ mod tests { TupleParam { name: None, kind: ParamType::FixedArray( - Box::new(ParamType::Tuple(vec![ParamType::Uint(48), ParamType::Address, ParamType::Address])), + Box::new(ParamType::Tuple(vec![ + ParamType::Uint(48).into(), + ParamType::Address.into(), + ParamType::Address.into() + ])), 2 ), internal_type: None @@ -376,8 +405,8 @@ mod tests { TupleParam { name: None, kind: ParamType::Tuple(vec![ - ParamType::Array(Box::new(ParamType::Tuple(vec![ParamType::Address]))), - ParamType::FixedArray(Box::new(ParamType::Tuple(vec![ParamType::Address])), 42,) + ParamType::Array(Box::new(ParamType::Tuple(vec![ParamType::Address.into()]))).into(), + ParamType::FixedArray(Box::new(ParamType::Tuple(vec![ParamType::Address.into()])), 42,).into() ]), internal_type: None }