git.delta.rocks / unique-network / refs/commits / 14137a17488f

difftreelog

feat add FIELDS_COUNT const in AbiType trait

Trubnikov Sergey2022-12-19parent: #3e8db54.patch.diff
in: master

6 files changed

modifiedcrates/evm-coder/procedural/src/abi_derive/derive_enum.rsdiffbeforeafterboth
--- a/crates/evm-coder/procedural/src/abi_derive/derive_enum.rs
+++ b/crates/evm-coder/procedural/src/abi_derive/derive_enum.rs
@@ -47,10 +47,11 @@
 	)
 }
 
-pub fn impl_enum_abi_type(name: &syn::Ident) -> proc_macro2::TokenStream {
+pub fn impl_enum_abi_type(name: &syn::Ident, option_count: usize) -> proc_macro2::TokenStream {
 	quote! {
 		impl ::evm_coder::abi::AbiType for #name {
 			const SIGNATURE: ::evm_coder::custom_signature::SignatureUnit = <u8 as ::evm_coder::abi::AbiType>::SIGNATURE;
+			const FIELDS_COUNT: usize = #option_count;
 
 			fn is_dynamic() -> bool {
 				<u8 as ::evm_coder::abi::AbiType>::is_dynamic()
modifiedcrates/evm-coder/procedural/src/abi_derive/derive_struct.rsdiffbeforeafterboth
--- a/crates/evm-coder/procedural/src/abi_derive/derive_struct.rs
+++ b/crates/evm-coder/procedural/src/abi_derive/derive_struct.rs
@@ -100,10 +100,12 @@
 pub fn impl_struct_abi_type(
 	name: &syn::Ident,
 	tuple_type: proc_macro2::TokenStream,
+	fields_count: usize,
 ) -> proc_macro2::TokenStream {
 	quote! {
 		impl ::evm_coder::abi::AbiType for #name {
 			const SIGNATURE: ::evm_coder::custom_signature::SignatureUnit = <#tuple_type as ::evm_coder::abi::AbiType>::SIGNATURE;
+			const FIELDS_COUNT: usize = #fields_count;
 			fn is_dynamic() -> bool {
 				<#tuple_type as ::evm_coder::abi::AbiType>::is_dynamic()
 			}
modifiedcrates/evm-coder/procedural/src/abi_derive/mod.rsdiffbeforeafterboth
--- a/crates/evm-coder/procedural/src/abi_derive/mod.rs
+++ b/crates/evm-coder/procedural/src/abi_derive/mod.rs
@@ -49,7 +49,7 @@
 	let struct_from_tuple = struct_from_tuple(name, is_named_fields, field_names.clone());
 
 	let can_be_plcaed_in_vec = impl_can_be_placed_in_vec(name);
-	let abi_type = impl_struct_abi_type(name, tuple_type.clone());
+	let abi_type = impl_struct_abi_type(name, tuple_type.clone(), params_count);
 	let abi_read = impl_struct_abi_read(name, tuple_type, tuple_names, struct_from_tuple);
 	let abi_write = impl_struct_abi_write(name, is_named_fields, tuple_ref_type, tuple_data);
 	let solidity_type = impl_struct_solidity_type(name, field_types.clone(), params_count);
@@ -83,7 +83,7 @@
 	let from = impl_enum_from_u8(name, enum_options.clone());
 	let solidity_option = impl_solidity_option(name, enum_options.clone());
 	let can_be_plcaed_in_vec = impl_can_be_placed_in_vec(name);
-	let abi_type = impl_enum_abi_type(name);
+	let abi_type = impl_enum_abi_type(name, option_count);
 	let abi_read = impl_enum_abi_read(name);
 	let abi_write = impl_enum_abi_write(name);
 	let solidity_type_name = impl_enum_solidity_type_name(name);
modifiedcrates/evm-coder/src/abi/impls.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/abi/impls.rs
+++ b/crates/evm-coder/src/abi/impls.rs
@@ -16,6 +16,7 @@
 
 		impl AbiType for $ty {
 			const SIGNATURE: SignatureUnit = make_signature!(new fixed(stringify!($name)));
+			const FIELDS_COUNT: usize = 1;
 
 			fn is_dynamic() -> bool {
 				$dynamic
@@ -96,6 +97,7 @@
 
 impl<T: AbiType> AbiType for &T {
 	const SIGNATURE: SignatureUnit = T::SIGNATURE;
+	const FIELDS_COUNT: usize = T::FIELDS_COUNT;
 
 	fn is_dynamic() -> bool {
 		T::is_dynamic()
@@ -125,6 +127,7 @@
 
 impl<T: AbiType> AbiType for Vec<T> {
 	const SIGNATURE: SignatureUnit = make_signature!(new nameof(T::SIGNATURE) fixed("[]"));
+	const FIELDS_COUNT: usize = 1;
 
 	fn is_dynamic() -> bool {
 		true
@@ -139,6 +142,7 @@
 
 impl AbiType for Property {
 	const SIGNATURE: SignatureUnit = make_signature!(new fixed("(string,bytes)"));
+	const FIELDS_COUNT: usize = 2;
 
 	fn is_dynamic() -> bool {
 		string::is_dynamic() || bytes::is_dynamic()
@@ -230,6 +234,7 @@
                 shift_left(1)
                 fixed(")")
             );
+			const FIELDS_COUNT: usize = 0 $(+ {let _ = <$ident as AbiType>::FIELDS_COUNT; 1})+;
 
 			fn is_dynamic() -> bool {
 				false
modifiedcrates/evm-coder/src/abi/traits.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/abi/traits.rs
+++ b/crates/evm-coder/src/abi/traits.rs
@@ -10,6 +10,9 @@
 	/// Signature for Etherium ABI.
 	const SIGNATURE: SignatureUnit;
 
+	/// Count of enum variants or struct fields.
+	const FIELDS_COUNT: usize;
+
 	/// Signature as str.
 	fn as_str() -> &'static str {
 		from_utf8(&Self::SIGNATURE.data[..Self::SIGNATURE.len]).expect("bad utf-8")
modifiedcrates/evm-coder/tests/abi_derive_generation.rsdiffbeforeafterboth
before · crates/evm-coder/tests/abi_derive_generation.rs
1mod test_struct {2	use evm_coder_procedural::AbiCoder;3	use evm_coder::types::bytes;45	#[test]6	fn empty_struct() {7		let t = trybuild::TestCases::new();8		t.compile_fail("tests/build_failed/abi_derive_struct_generation.rs");9	}1011	#[derive(AbiCoder, PartialEq, Debug)]12	struct TypeStruct1SimpleParam {13		_a: u8,14	}1516	#[derive(AbiCoder, PartialEq, Debug)]17	struct TypeStruct1DynamicParam {18		_a: String,19	}2021	#[derive(AbiCoder, PartialEq, Debug)]22	struct TypeStruct2SimpleParam {23		_a: u8,24		_b: u32,25	}2627	#[derive(AbiCoder, PartialEq, Debug)]28	struct TypeStruct2DynamicParam {29		_a: String,30		_b: bytes,31	}3233	#[derive(AbiCoder, PartialEq, Debug)]34	struct TypeStruct2MixedParam {35		_a: u8,36		_b: bytes,37	}3839	#[derive(AbiCoder, PartialEq, Debug)]40	struct TypeStruct1DerivedSimpleParam {41		_a: TypeStruct1SimpleParam,42	}4344	#[derive(AbiCoder, PartialEq, Debug)]45	struct TypeStruct2DerivedSimpleParam {46		_a: TypeStruct1SimpleParam,47		_b: TypeStruct2SimpleParam,48	}4950	#[derive(AbiCoder, PartialEq, Debug)]51	struct TypeStruct1DerivedDynamicParam {52		_a: TypeStruct1DynamicParam,53	}5455	#[derive(AbiCoder, PartialEq, Debug)]56	struct TypeStruct2DerivedDynamicParam {57		_a: TypeStruct1DynamicParam,58		_b: TypeStruct2DynamicParam,59	}6061	/// Some docs62	/// At multi63	/// line64	#[derive(AbiCoder, PartialEq, Debug)]65	struct TypeStruct3DerivedMixedParam {66		/// Docs for A67		/// multi68		/// line69		_a: TypeStruct1SimpleParam,70		/// Docs for B71		_b: TypeStruct2DynamicParam,72		/// Docs for C73		_c: TypeStruct2MixedParam,74	}7576	#[test]77	#[cfg(feature = "stubgen")]78	fn struct_collect_type_struct3_derived_mixed_param() {79		assert_eq!(80			<TypeStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::name(),81			"TypeStruct3DerivedMixedParam"82		);83		similar_asserts::assert_eq!(84			<TypeStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::declaration(),85			r#"/// @dev Some docs86/// At multi87/// line88struct TypeStruct3DerivedMixedParam {89	/// @dev Docs for A90	/// multi91	/// line92	TypeStruct1SimpleParam _a;93	/// @dev Docs for B94	TypeStruct2DynamicParam _b;95	/// @dev Docs for C96	TypeStruct2MixedParam _c;97}98"#99		);100	}101102	#[test]103	fn impl_abi_type_signature() {104		assert_eq!(105			<TypeStruct1SimpleParam as evm_coder::abi::AbiType>::SIGNATURE106				.as_str()107				.unwrap(),108			"(uint8)"109		);110		assert_eq!(111			<TypeStruct1DynamicParam as evm_coder::abi::AbiType>::SIGNATURE112				.as_str()113				.unwrap(),114			"(string)"115		);116		assert_eq!(117			<TypeStruct2SimpleParam as evm_coder::abi::AbiType>::SIGNATURE118				.as_str()119				.unwrap(),120			"(uint8,uint32)"121		);122		assert_eq!(123			<TypeStruct2DynamicParam as evm_coder::abi::AbiType>::SIGNATURE124				.as_str()125				.unwrap(),126			"(string,bytes)"127		);128		assert_eq!(129			<TypeStruct2MixedParam as evm_coder::abi::AbiType>::SIGNATURE130				.as_str()131				.unwrap(),132			"(uint8,bytes)"133		);134		assert_eq!(135			<TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE136				.as_str()137				.unwrap(),138			"((uint8))"139		);140		assert_eq!(141			<TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE142				.as_str()143				.unwrap(),144			"((uint8),(uint8,uint32))"145		);146		assert_eq!(147			<TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE148				.as_str()149				.unwrap(),150			"((string))"151		);152		assert_eq!(153			<TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE154				.as_str()155				.unwrap(),156			"((string),(string,bytes))"157		);158		assert_eq!(159			<TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::SIGNATURE160				.as_str()161				.unwrap(),162			"((uint8),(string,bytes),(uint8,bytes))"163		);164	}165166	#[test]167	fn impl_abi_type_is_dynamic() {168		assert_eq!(169			<TypeStruct1SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),170			false171		);172		assert_eq!(173			<TypeStruct1DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),174			true175		);176		assert_eq!(177			<TypeStruct2SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),178			false179		);180		assert_eq!(181			<TypeStruct2DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),182			true183		);184		assert_eq!(185			<TypeStruct2MixedParam as evm_coder::abi::AbiType>::is_dynamic(),186			true187		);188		assert_eq!(189			<TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),190			false191		);192		assert_eq!(193			<TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),194			false195		);196		assert_eq!(197			<TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),198			true199		);200		assert_eq!(201			<TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),202			true203		);204		assert_eq!(205			<TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::is_dynamic(),206			true207		);208	}209210	#[test]211	fn impl_abi_type_size() {212		const ABI_ALIGNMENT: usize = 32;213		assert_eq!(214			<TypeStruct1SimpleParam as evm_coder::abi::AbiType>::size(),215			ABI_ALIGNMENT216		);217		assert_eq!(218			<TypeStruct1DynamicParam as evm_coder::abi::AbiType>::size(),219			ABI_ALIGNMENT220		);221		assert_eq!(222			<TypeStruct2SimpleParam as evm_coder::abi::AbiType>::size(),223			ABI_ALIGNMENT * 2224		);225		assert_eq!(226			<TypeStruct2DynamicParam as evm_coder::abi::AbiType>::size(),227			ABI_ALIGNMENT * 2228		);229		assert_eq!(230			<TypeStruct2MixedParam as evm_coder::abi::AbiType>::size(),231			ABI_ALIGNMENT * 2232		);233		assert_eq!(234			<TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::size(),235			ABI_ALIGNMENT236		);237		assert_eq!(238			<TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::size(),239			ABI_ALIGNMENT * 3240		);241		assert_eq!(242			<TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::size(),243			ABI_ALIGNMENT244		);245		assert_eq!(246			<TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::size(),247			ABI_ALIGNMENT * 3248		);249		assert_eq!(250			<TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::size(),251			ABI_ALIGNMENT * 5252		);253	}254255	#[derive(AbiCoder, PartialEq, Debug)]256	struct TupleStruct1SimpleParam(u8);257258	#[derive(AbiCoder, PartialEq, Debug)]259	struct TupleStruct1DynamicParam(String);260261	#[derive(AbiCoder, PartialEq, Debug)]262	struct TupleStruct2SimpleParam(u8, u32);263264	#[derive(AbiCoder, PartialEq, Debug)]265	struct TupleStruct2DynamicParam(String, bytes);266267	#[derive(AbiCoder, PartialEq, Debug)]268	struct TupleStruct2MixedParam(u8, bytes);269270	#[derive(AbiCoder, PartialEq, Debug)]271	struct TupleStruct1DerivedSimpleParam(TupleStruct1SimpleParam);272273	#[derive(AbiCoder, PartialEq, Debug)]274	struct TupleStruct2DerivedSimpleParam(TupleStruct1SimpleParam, TupleStruct2SimpleParam);275276	#[derive(AbiCoder, PartialEq, Debug)]277	struct TupleStruct1DerivedDynamicParam(TupleStruct1DynamicParam);278279	#[derive(AbiCoder, PartialEq, Debug)]280	struct TupleStruct2DerivedDynamicParam(TupleStruct1DynamicParam, TupleStruct2DynamicParam);281282	/// Some docs283	/// At multi284	/// line285	#[derive(AbiCoder, PartialEq, Debug)]286	struct TupleStruct3DerivedMixedParam(287		/// Docs for A288		/// multi289		/// line290		TupleStruct1SimpleParam,291		TupleStruct2DynamicParam,292		/// Docs for C293		TupleStruct2MixedParam,294	);295296	#[test]297	#[cfg(feature = "stubgen")]298	fn struct_collect_tuple_struct3_derived_mixed_param() {299		assert_eq!(300			<TupleStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::name(),301			"TupleStruct3DerivedMixedParam"302		);303		similar_asserts::assert_eq!(304			<TupleStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::declaration(),305			r#"/// @dev Some docs306/// At multi307/// line308struct TupleStruct3DerivedMixedParam {309	/// @dev Docs for A310	/// multi311	/// line312	TupleStruct1SimpleParam field0;313	TupleStruct2DynamicParam field1;314	/// @dev Docs for C315	TupleStruct2MixedParam field2;316}317"#318		);319	}320321	#[test]322	fn impl_abi_type_signature_same_for_structs() {323		assert_eq!(324			<TypeStruct1SimpleParam as evm_coder::abi::AbiType>::SIGNATURE325				.as_str()326				.unwrap(),327			<TupleStruct1SimpleParam as evm_coder::abi::AbiType>::SIGNATURE328				.as_str()329				.unwrap()330		);331		assert_eq!(332			<TypeStruct1DynamicParam as evm_coder::abi::AbiType>::SIGNATURE333				.as_str()334				.unwrap(),335			<TupleStruct1DynamicParam as evm_coder::abi::AbiType>::SIGNATURE336				.as_str()337				.unwrap()338		);339		assert_eq!(340			<TypeStruct2SimpleParam as evm_coder::abi::AbiType>::SIGNATURE341				.as_str()342				.unwrap(),343			<TupleStruct2SimpleParam as evm_coder::abi::AbiType>::SIGNATURE344				.as_str()345				.unwrap()346		);347		assert_eq!(348			<TypeStruct2DynamicParam as evm_coder::abi::AbiType>::SIGNATURE349				.as_str()350				.unwrap(),351			<TupleStruct2DynamicParam as evm_coder::abi::AbiType>::SIGNATURE352				.as_str()353				.unwrap()354		);355		assert_eq!(356			<TypeStruct2MixedParam as evm_coder::abi::AbiType>::SIGNATURE357				.as_str()358				.unwrap(),359			<TupleStruct2MixedParam as evm_coder::abi::AbiType>::SIGNATURE360				.as_str()361				.unwrap(),362		);363		assert_eq!(364			<TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE365				.as_str()366				.unwrap(),367			<TupleStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE368				.as_str()369				.unwrap(),370		);371		assert_eq!(372			<TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE373				.as_str()374				.unwrap(),375			<TupleStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE376				.as_str()377				.unwrap(),378		);379		assert_eq!(380			<TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE381				.as_str()382				.unwrap(),383			<TupleStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE384				.as_str()385				.unwrap(),386		);387		assert_eq!(388			<TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE389				.as_str()390				.unwrap(),391			<TupleStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE392				.as_str()393				.unwrap(),394		);395		assert_eq!(396			<TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::SIGNATURE397				.as_str()398				.unwrap(),399			<TupleStruct3DerivedMixedParam as evm_coder::abi::AbiType>::SIGNATURE400				.as_str()401				.unwrap(),402		);403	}404405	#[test]406	fn impl_abi_type_is_dynamic_same_for_structs() {407		assert_eq!(408			<TypeStruct1SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),409			<TupleStruct1SimpleParam as evm_coder::abi::AbiType>::is_dynamic()410		);411		assert_eq!(412			<TypeStruct1DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),413			<TupleStruct1DynamicParam as evm_coder::abi::AbiType>::is_dynamic()414		);415		assert_eq!(416			<TypeStruct2SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),417			<TupleStruct2SimpleParam as evm_coder::abi::AbiType>::is_dynamic()418		);419		assert_eq!(420			<TypeStruct2DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),421			<TupleStruct2DynamicParam as evm_coder::abi::AbiType>::is_dynamic()422		);423		assert_eq!(424			<TypeStruct2MixedParam as evm_coder::abi::AbiType>::is_dynamic(),425			<TupleStruct2MixedParam as evm_coder::abi::AbiType>::is_dynamic()426		);427		assert_eq!(428			<TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),429			<TupleStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic()430		);431		assert_eq!(432			<TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),433			<TupleStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic()434		);435		assert_eq!(436			<TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),437			<TupleStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic()438		);439		assert_eq!(440			<TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),441			<TupleStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic()442		);443		assert_eq!(444			<TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::is_dynamic(),445			<TupleStruct3DerivedMixedParam as evm_coder::abi::AbiType>::is_dynamic()446		);447	}448449	#[test]450	fn impl_abi_type_size_same_for_structs() {451		assert_eq!(452			<TypeStruct1SimpleParam as evm_coder::abi::AbiType>::size(),453			<TupleStruct1SimpleParam as evm_coder::abi::AbiType>::size()454		);455		assert_eq!(456			<TypeStruct1DynamicParam as evm_coder::abi::AbiType>::size(),457			<TupleStruct1DynamicParam as evm_coder::abi::AbiType>::size()458		);459		assert_eq!(460			<TypeStruct2SimpleParam as evm_coder::abi::AbiType>::size(),461			<TupleStruct2SimpleParam as evm_coder::abi::AbiType>::size()462		);463		assert_eq!(464			<TypeStruct2DynamicParam as evm_coder::abi::AbiType>::size(),465			<TupleStruct2DynamicParam as evm_coder::abi::AbiType>::size()466		);467		assert_eq!(468			<TypeStruct2MixedParam as evm_coder::abi::AbiType>::size(),469			<TupleStruct2MixedParam as evm_coder::abi::AbiType>::size()470		);471		assert_eq!(472			<TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::size(),473			<TupleStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::size()474		);475		assert_eq!(476			<TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::size(),477			<TupleStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::size()478		);479		assert_eq!(480			<TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::size(),481			<TupleStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::size()482		);483		assert_eq!(484			<TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::size(),485			<TupleStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::size()486		);487		assert_eq!(488			<TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::size(),489			<TupleStruct3DerivedMixedParam as evm_coder::abi::AbiType>::size()490		);491	}492493	const FUNCTION_IDENTIFIER: u32 = 0xdeadbeef;494495	fn test_impl<Tuple, TupleStruct, TypeStruct>(496		tuple_data: Tuple,497		tuple_struct_data: TupleStruct,498		type_struct_data: TypeStruct,499	) where500		TypeStruct: evm_coder::abi::AbiWrite501			+ evm_coder::abi::AbiRead502			+ std::cmp::PartialEq503			+ std::fmt::Debug,504		TupleStruct: evm_coder::abi::AbiWrite505			+ evm_coder::abi::AbiRead506			+ std::cmp::PartialEq507			+ std::fmt::Debug,508		Tuple: evm_coder::abi::AbiWrite509			+ evm_coder::abi::AbiRead510			+ std::cmp::PartialEq511			+ std::fmt::Debug,512	{513		let encoded_type_struct = test_abi_write_impl(&type_struct_data);514		let encoded_tuple_struct = test_abi_write_impl(&tuple_struct_data);515		let encoded_tuple = test_abi_write_impl(&tuple_data);516517		similar_asserts::assert_eq!(encoded_tuple, encoded_type_struct);518		similar_asserts::assert_eq!(encoded_tuple, encoded_tuple_struct);519520		{521			let (_, mut decoder) = evm_coder::abi::AbiReader::new_call(&encoded_tuple).unwrap();522			let restored_struct_data = <TypeStruct>::abi_read(&mut decoder).unwrap();523			assert_eq!(restored_struct_data, type_struct_data);524		}525		{526			let (_, mut decoder) = evm_coder::abi::AbiReader::new_call(&encoded_tuple).unwrap();527			let restored_struct_data = <TupleStruct>::abi_read(&mut decoder).unwrap();528			assert_eq!(restored_struct_data, tuple_struct_data);529		}530531		{532			let (_, mut decoder) =533				evm_coder::abi::AbiReader::new_call(&encoded_type_struct).unwrap();534			let restored_tuple_data = <Tuple>::abi_read(&mut decoder).unwrap();535			assert_eq!(restored_tuple_data, tuple_data);536		}537		{538			let (_, mut decoder) =539				evm_coder::abi::AbiReader::new_call(&encoded_tuple_struct).unwrap();540			let restored_tuple_data = <Tuple>::abi_read(&mut decoder).unwrap();541			assert_eq!(restored_tuple_data, tuple_data);542		}543	}544545	fn test_abi_write_impl<A>(data: &A) -> Vec<u8>546	where547		A: evm_coder::abi::AbiWrite548			+ evm_coder::abi::AbiRead549			+ std::cmp::PartialEq550			+ std::fmt::Debug,551	{552		let mut writer = evm_coder::abi::AbiWriter::new_call(FUNCTION_IDENTIFIER);553		data.abi_write(&mut writer);554		let encoded_tuple = writer.finish();555		encoded_tuple556	}557558	#[test]559	fn codec_struct_1_simple() {560		let _a = 0xff;561		test_impl::<(u8,), TupleStruct1SimpleParam, TypeStruct1SimpleParam>(562			(_a,),563			TupleStruct1SimpleParam(_a),564			TypeStruct1SimpleParam { _a },565		);566	}567568	#[test]569	fn codec_struct_1_dynamic() {570		let _a: String = "some string".into();571		test_impl::<(String,), TupleStruct1DynamicParam, TypeStruct1DynamicParam>(572			(_a.clone(),),573			TupleStruct1DynamicParam(_a.clone()),574			TypeStruct1DynamicParam { _a },575		);576	}577578	#[test]579	fn codec_struct_1_derived_simple() {580		let _a: u8 = 0xff;581		test_impl::<((u8,),), TupleStruct1DerivedSimpleParam, TypeStruct1DerivedSimpleParam>(582			((_a,),),583			TupleStruct1DerivedSimpleParam(TupleStruct1SimpleParam(_a)),584			TypeStruct1DerivedSimpleParam {585				_a: TypeStruct1SimpleParam { _a },586			},587		);588	}589590	#[test]591	fn codec_struct_1_derived_dynamic() {592		let _a: String = "some string".into();593		test_impl::<((String,),), TupleStruct1DerivedDynamicParam, TypeStruct1DerivedDynamicParam>(594			((_a.clone(),),),595			TupleStruct1DerivedDynamicParam(TupleStruct1DynamicParam(_a.clone())),596			TypeStruct1DerivedDynamicParam {597				_a: TypeStruct1DynamicParam { _a },598			},599		);600	}601602	#[test]603	fn codec_struct_2_simple() {604		let _a = 0xff;605		let _b = 0xbeefbaba;606		test_impl::<(u8, u32), TupleStruct2SimpleParam, TypeStruct2SimpleParam>(607			(_a, _b),608			TupleStruct2SimpleParam(_a, _b),609			TypeStruct2SimpleParam { _a, _b },610		);611	}612613	#[test]614	fn codec_struct_2_dynamic() {615		let _a: String = "some string".into();616		let _b: bytes = bytes(vec![0x11, 0x22, 0x33]);617		test_impl::<(String, bytes), TupleStruct2DynamicParam, TypeStruct2DynamicParam>(618			(_a.clone(), _b.clone()),619			TupleStruct2DynamicParam(_a.clone(), _b.clone()),620			TypeStruct2DynamicParam { _a, _b },621		);622	}623624	#[test]625	fn codec_struct_2_mixed() {626		let _a: u8 = 0xff;627		let _b: bytes = bytes(vec![0x11, 0x22, 0x33]);628		test_impl::<(u8, bytes), TupleStruct2MixedParam, TypeStruct2MixedParam>(629			(_a.clone(), _b.clone()),630			TupleStruct2MixedParam(_a.clone(), _b.clone()),631			TypeStruct2MixedParam { _a, _b },632		);633	}634635	#[test]636	fn codec_struct_2_derived_simple() {637		let _a = 0xff;638		let _b = 0xbeefbaba;639		test_impl::<640			((u8,), (u8, u32)),641			TupleStruct2DerivedSimpleParam,642			TypeStruct2DerivedSimpleParam,643		>(644			((_a,), (_a, _b)),645			TupleStruct2DerivedSimpleParam(646				TupleStruct1SimpleParam(_a),647				TupleStruct2SimpleParam(_a, _b),648			),649			TypeStruct2DerivedSimpleParam {650				_a: TypeStruct1SimpleParam { _a },651				_b: TypeStruct2SimpleParam { _a, _b },652			},653		);654	}655656	#[test]657	fn codec_struct_2_derived_dynamic() {658		let _a = "some string".to_string();659		let _b = bytes(vec![0x11, 0x22, 0x33]);660		test_impl::<661			((String,), (String, bytes)),662			TupleStruct2DerivedDynamicParam,663			TypeStruct2DerivedDynamicParam,664		>(665			((_a.clone(),), (_a.clone(), _b.clone())),666			TupleStruct2DerivedDynamicParam(667				TupleStruct1DynamicParam(_a.clone()),668				TupleStruct2DynamicParam(_a.clone(), _b.clone()),669			),670			TypeStruct2DerivedDynamicParam {671				_a: TypeStruct1DynamicParam { _a: _a.clone() },672				_b: TypeStruct2DynamicParam { _a, _b },673			},674		);675	}676677	#[test]678	fn codec_struct_3_derived_mixed() {679		let int = 0xff;680		let by = bytes(vec![0x11, 0x22, 0x33]);681		let string = "some string".to_string();682		test_impl::<683			((u8,), (String, bytes), (u8, bytes)),684			TupleStruct3DerivedMixedParam,685			TypeStruct3DerivedMixedParam,686		>(687			((int,), (string.clone(), by.clone()), (int, by.clone())),688			TupleStruct3DerivedMixedParam(689				TupleStruct1SimpleParam(int),690				TupleStruct2DynamicParam(string.clone(), by.clone()),691				TupleStruct2MixedParam(int, by.clone()),692			),693			TypeStruct3DerivedMixedParam {694				_a: TypeStruct1SimpleParam { _a: int },695				_b: TypeStruct2DynamicParam {696					_a: string.clone(),697					_b: by.clone(),698				},699				_c: TypeStruct2MixedParam { _a: int, _b: by },700			},701		);702	}703704	#[derive(AbiCoder, PartialEq, Debug)]705	struct TypeStruct2SimpleStruct1Simple {706		_a: TypeStruct2SimpleParam,707		_b: TypeStruct2SimpleParam,708		_c: u8,709	}710	#[derive(AbiCoder, PartialEq, Debug)]711	struct TupleStruct2SimpleStruct1Simple(TupleStruct2SimpleParam, TupleStruct2SimpleParam, u8);712713	#[test]714	fn codec_struct_2_struct_simple_1_simple() {715		let _a = 0xff;716		let _b = 0xbeefbaba;717		test_impl::<718			((u8, u32), (u8, u32), u8),719			TupleStruct2SimpleStruct1Simple,720			TypeStruct2SimpleStruct1Simple,721		>(722			((_a, _b), (_a, _b), _a),723			TupleStruct2SimpleStruct1Simple(724				TupleStruct2SimpleParam(_a, _b),725				TupleStruct2SimpleParam(_a, _b),726				_a,727			),728			TypeStruct2SimpleStruct1Simple {729				_a: TypeStruct2SimpleParam { _a, _b },730				_b: TypeStruct2SimpleParam { _a, _b },731				_c: _a,732			},733		);734	}735}736737mod test_enum {738	use evm_coder::AbiCoder;739740	/// Some docs741	/// At multi742	/// line743	#[derive(AbiCoder, Debug, PartialEq, Default, Clone, Copy)]744	#[repr(u8)]745	enum Color {746		/// Docs for Red747		/// multi748		/// line749		Red,750		Green,751		/// Docs for Blue752		#[default]753		Blue,754	}755756	#[test]757	fn empty() {}758759	#[test]760	fn bad_enums() {761		let t = trybuild::TestCases::new();762		t.compile_fail("tests/build_failed/abi_derive_enum_generation.rs");763	}764765	#[test]766	fn impl_abi_type_signature_same_for_structs() {767		assert_eq!(768			<Color as evm_coder::abi::AbiType>::SIGNATURE769				.as_str()770				.unwrap(),771			<u8 as evm_coder::abi::AbiType>::SIGNATURE.as_str().unwrap()772		);773	}774775	#[test]776	fn impl_abi_type_is_dynamic_same_for_structs() {777		assert_eq!(778			<Color as evm_coder::abi::AbiType>::is_dynamic(),779			<u8 as evm_coder::abi::AbiType>::is_dynamic()780		);781	}782783	#[test]784	fn impl_abi_type_size_same_for_structs() {785		assert_eq!(786			<Color as evm_coder::abi::AbiType>::size(),787			<u8 as evm_coder::abi::AbiType>::size()788		);789	}790791	#[test]792	fn test_coder() {793		const FUNCTION_IDENTIFIER: u32 = 0xdeadbeef;794795		let encoded_enum = {796			let mut writer = evm_coder::abi::AbiWriter::new_call(FUNCTION_IDENTIFIER);797			<Color as evm_coder::abi::AbiWrite>::abi_write(&Color::Green, &mut writer);798			writer.finish()799		};800801		let encoded_u8 = {802			let mut writer = evm_coder::abi::AbiWriter::new_call(FUNCTION_IDENTIFIER);803			<u8 as evm_coder::abi::AbiWrite>::abi_write(&(Color::Green as u8), &mut writer);804			writer.finish()805		};806807		similar_asserts::assert_eq!(encoded_enum, encoded_u8);808809		{810			let (_, mut decoder) = evm_coder::abi::AbiReader::new_call(&encoded_enum).unwrap();811			let restored_enum_data =812				<Color as evm_coder::abi::AbiRead>::abi_read(&mut decoder).unwrap();813			assert_eq!(restored_enum_data, Color::Green);814		}815	}816817	#[test]818	#[cfg(feature = "stubgen")]819	fn struct_collect_enum() {820		assert_eq!(821			<Color as ::evm_coder::solidity::StructCollect>::name(),822			"Color"823		);824		similar_asserts::assert_eq!(825			<Color as ::evm_coder::solidity::StructCollect>::declaration(),826			r#"/// @dev Some docs827/// At multi828/// line829enum Color {830	/// @dev Docs for Red831	/// multi832	/// line833	Red,834	Green,835	/// @dev Docs for Blue836	Blue837}838"#839		);840	}841}
after · crates/evm-coder/tests/abi_derive_generation.rs
1mod test_struct {2	use evm_coder_procedural::AbiCoder;3	use evm_coder::types::bytes;45	#[test]6	fn empty_struct() {7		let t = trybuild::TestCases::new();8		t.compile_fail("tests/build_failed/abi_derive_struct_generation.rs");9	}1011	#[derive(AbiCoder, PartialEq, Debug)]12	struct TypeStruct1SimpleParam {13		_a: u8,14	}1516	#[derive(AbiCoder, PartialEq, Debug)]17	struct TypeStruct1DynamicParam {18		_a: String,19	}2021	#[derive(AbiCoder, PartialEq, Debug)]22	struct TypeStruct2SimpleParam {23		_a: u8,24		_b: u32,25	}2627	#[derive(AbiCoder, PartialEq, Debug)]28	struct TypeStruct2DynamicParam {29		_a: String,30		_b: bytes,31	}3233	#[derive(AbiCoder, PartialEq, Debug)]34	struct TypeStruct2MixedParam {35		_a: u8,36		_b: bytes,37	}3839	#[derive(AbiCoder, PartialEq, Debug)]40	struct TypeStruct1DerivedSimpleParam {41		_a: TypeStruct1SimpleParam,42	}4344	#[derive(AbiCoder, PartialEq, Debug)]45	struct TypeStruct2DerivedSimpleParam {46		_a: TypeStruct1SimpleParam,47		_b: TypeStruct2SimpleParam,48	}4950	#[derive(AbiCoder, PartialEq, Debug)]51	struct TypeStruct1DerivedDynamicParam {52		_a: TypeStruct1DynamicParam,53	}5455	#[derive(AbiCoder, PartialEq, Debug)]56	struct TypeStruct2DerivedDynamicParam {57		_a: TypeStruct1DynamicParam,58		_b: TypeStruct2DynamicParam,59	}6061	/// Some docs62	/// At multi63	/// line64	#[derive(AbiCoder, PartialEq, Debug)]65	struct TypeStruct3DerivedMixedParam {66		/// Docs for A67		/// multi68		/// line69		_a: TypeStruct1SimpleParam,70		/// Docs for B71		_b: TypeStruct2DynamicParam,72		/// Docs for C73		_c: TypeStruct2MixedParam,74	}7576	#[test]77	#[cfg(feature = "stubgen")]78	fn struct_collect_type_struct3_derived_mixed_param() {79		assert_eq!(80			<TypeStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::name(),81			"TypeStruct3DerivedMixedParam"82		);83		similar_asserts::assert_eq!(84			<TypeStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::declaration(),85			r#"/// @dev Some docs86/// At multi87/// line88struct TypeStruct3DerivedMixedParam {89	/// @dev Docs for A90	/// multi91	/// line92	TypeStruct1SimpleParam _a;93	/// @dev Docs for B94	TypeStruct2DynamicParam _b;95	/// @dev Docs for C96	TypeStruct2MixedParam _c;97}98"#99		);100	}101102	#[test]103	fn impl_abi_type_signature() {104		assert_eq!(105			<TypeStruct1SimpleParam as evm_coder::abi::AbiType>::SIGNATURE106				.as_str()107				.unwrap(),108			"(uint8)"109		);110		assert_eq!(111			<TypeStruct1DynamicParam as evm_coder::abi::AbiType>::SIGNATURE112				.as_str()113				.unwrap(),114			"(string)"115		);116		assert_eq!(117			<TypeStruct2SimpleParam as evm_coder::abi::AbiType>::SIGNATURE118				.as_str()119				.unwrap(),120			"(uint8,uint32)"121		);122		assert_eq!(123			<TypeStruct2DynamicParam as evm_coder::abi::AbiType>::SIGNATURE124				.as_str()125				.unwrap(),126			"(string,bytes)"127		);128		assert_eq!(129			<TypeStruct2MixedParam as evm_coder::abi::AbiType>::SIGNATURE130				.as_str()131				.unwrap(),132			"(uint8,bytes)"133		);134		assert_eq!(135			<TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE136				.as_str()137				.unwrap(),138			"((uint8))"139		);140		assert_eq!(141			<TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE142				.as_str()143				.unwrap(),144			"((uint8),(uint8,uint32))"145		);146		assert_eq!(147			<TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE148				.as_str()149				.unwrap(),150			"((string))"151		);152		assert_eq!(153			<TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE154				.as_str()155				.unwrap(),156			"((string),(string,bytes))"157		);158		assert_eq!(159			<TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::SIGNATURE160				.as_str()161				.unwrap(),162			"((uint8),(string,bytes),(uint8,bytes))"163		);164	}165166	#[test]167	fn impl_abi_type_fields_count() {168		assert_eq!(169			<TypeStruct1SimpleParam as evm_coder::abi::AbiType>::FIELDS_COUNT,170			1171		);172		assert_eq!(173			<TypeStruct1DynamicParam as evm_coder::abi::AbiType>::FIELDS_COUNT,174			1175		);176		assert_eq!(177			<TypeStruct2SimpleParam as evm_coder::abi::AbiType>::FIELDS_COUNT,178			2179		);180		assert_eq!(181			<TypeStruct2DynamicParam as evm_coder::abi::AbiType>::FIELDS_COUNT,182			2183		);184		assert_eq!(185			<TypeStruct2MixedParam as evm_coder::abi::AbiType>::FIELDS_COUNT,186			2187		);188		assert_eq!(189			<TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::FIELDS_COUNT,190			1191		);192		assert_eq!(193			<TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::FIELDS_COUNT,194			2195		);196		assert_eq!(197			<TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::FIELDS_COUNT,198			2199		);200		assert_eq!(201			<TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::FIELDS_COUNT,202			2203		);204		assert_eq!(205			<TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::FIELDS_COUNT,206			3207		);208	}209210	#[test]211	fn impl_abi_type_is_dynamic() {212		assert_eq!(213			<TypeStruct1SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),214			false215		);216		assert_eq!(217			<TypeStruct1DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),218			true219		);220		assert_eq!(221			<TypeStruct2SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),222			false223		);224		assert_eq!(225			<TypeStruct2DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),226			true227		);228		assert_eq!(229			<TypeStruct2MixedParam as evm_coder::abi::AbiType>::is_dynamic(),230			true231		);232		assert_eq!(233			<TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),234			false235		);236		assert_eq!(237			<TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),238			false239		);240		assert_eq!(241			<TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),242			true243		);244		assert_eq!(245			<TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),246			true247		);248		assert_eq!(249			<TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::is_dynamic(),250			true251		);252	}253254	#[test]255	fn impl_abi_type_size() {256		const ABI_ALIGNMENT: usize = 32;257		assert_eq!(258			<TypeStruct1SimpleParam as evm_coder::abi::AbiType>::size(),259			ABI_ALIGNMENT260		);261		assert_eq!(262			<TypeStruct1DynamicParam as evm_coder::abi::AbiType>::size(),263			ABI_ALIGNMENT264		);265		assert_eq!(266			<TypeStruct2SimpleParam as evm_coder::abi::AbiType>::size(),267			ABI_ALIGNMENT * 2268		);269		assert_eq!(270			<TypeStruct2DynamicParam as evm_coder::abi::AbiType>::size(),271			ABI_ALIGNMENT * 2272		);273		assert_eq!(274			<TypeStruct2MixedParam as evm_coder::abi::AbiType>::size(),275			ABI_ALIGNMENT * 2276		);277		assert_eq!(278			<TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::size(),279			ABI_ALIGNMENT280		);281		assert_eq!(282			<TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::size(),283			ABI_ALIGNMENT * 3284		);285		assert_eq!(286			<TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::size(),287			ABI_ALIGNMENT288		);289		assert_eq!(290			<TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::size(),291			ABI_ALIGNMENT * 3292		);293		assert_eq!(294			<TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::size(),295			ABI_ALIGNMENT * 5296		);297	}298299	#[derive(AbiCoder, PartialEq, Debug)]300	struct TupleStruct1SimpleParam(u8);301302	#[derive(AbiCoder, PartialEq, Debug)]303	struct TupleStruct1DynamicParam(String);304305	#[derive(AbiCoder, PartialEq, Debug)]306	struct TupleStruct2SimpleParam(u8, u32);307308	#[derive(AbiCoder, PartialEq, Debug)]309	struct TupleStruct2DynamicParam(String, bytes);310311	#[derive(AbiCoder, PartialEq, Debug)]312	struct TupleStruct2MixedParam(u8, bytes);313314	#[derive(AbiCoder, PartialEq, Debug)]315	struct TupleStruct1DerivedSimpleParam(TupleStruct1SimpleParam);316317	#[derive(AbiCoder, PartialEq, Debug)]318	struct TupleStruct2DerivedSimpleParam(TupleStruct1SimpleParam, TupleStruct2SimpleParam);319320	#[derive(AbiCoder, PartialEq, Debug)]321	struct TupleStruct1DerivedDynamicParam(TupleStruct1DynamicParam);322323	#[derive(AbiCoder, PartialEq, Debug)]324	struct TupleStruct2DerivedDynamicParam(TupleStruct1DynamicParam, TupleStruct2DynamicParam);325326	/// Some docs327	/// At multi328	/// line329	#[derive(AbiCoder, PartialEq, Debug)]330	struct TupleStruct3DerivedMixedParam(331		/// Docs for A332		/// multi333		/// line334		TupleStruct1SimpleParam,335		TupleStruct2DynamicParam,336		/// Docs for C337		TupleStruct2MixedParam,338	);339340	#[test]341	#[cfg(feature = "stubgen")]342	fn struct_collect_tuple_struct3_derived_mixed_param() {343		assert_eq!(344			<TupleStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::name(),345			"TupleStruct3DerivedMixedParam"346		);347		similar_asserts::assert_eq!(348			<TupleStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::declaration(),349			r#"/// @dev Some docs350/// At multi351/// line352struct TupleStruct3DerivedMixedParam {353	/// @dev Docs for A354	/// multi355	/// line356	TupleStruct1SimpleParam field0;357	TupleStruct2DynamicParam field1;358	/// @dev Docs for C359	TupleStruct2MixedParam field2;360}361"#362		);363	}364365	#[test]366	fn impl_abi_type_signature_same_for_structs() {367		assert_eq!(368			<TypeStruct1SimpleParam as evm_coder::abi::AbiType>::SIGNATURE369				.as_str()370				.unwrap(),371			<TupleStruct1SimpleParam as evm_coder::abi::AbiType>::SIGNATURE372				.as_str()373				.unwrap()374		);375		assert_eq!(376			<TypeStruct1DynamicParam as evm_coder::abi::AbiType>::SIGNATURE377				.as_str()378				.unwrap(),379			<TupleStruct1DynamicParam as evm_coder::abi::AbiType>::SIGNATURE380				.as_str()381				.unwrap()382		);383		assert_eq!(384			<TypeStruct2SimpleParam as evm_coder::abi::AbiType>::SIGNATURE385				.as_str()386				.unwrap(),387			<TupleStruct2SimpleParam as evm_coder::abi::AbiType>::SIGNATURE388				.as_str()389				.unwrap()390		);391		assert_eq!(392			<TypeStruct2DynamicParam as evm_coder::abi::AbiType>::SIGNATURE393				.as_str()394				.unwrap(),395			<TupleStruct2DynamicParam as evm_coder::abi::AbiType>::SIGNATURE396				.as_str()397				.unwrap()398		);399		assert_eq!(400			<TypeStruct2MixedParam as evm_coder::abi::AbiType>::SIGNATURE401				.as_str()402				.unwrap(),403			<TupleStruct2MixedParam as evm_coder::abi::AbiType>::SIGNATURE404				.as_str()405				.unwrap(),406		);407		assert_eq!(408			<TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE409				.as_str()410				.unwrap(),411			<TupleStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE412				.as_str()413				.unwrap(),414		);415		assert_eq!(416			<TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE417				.as_str()418				.unwrap(),419			<TupleStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE420				.as_str()421				.unwrap(),422		);423		assert_eq!(424			<TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE425				.as_str()426				.unwrap(),427			<TupleStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE428				.as_str()429				.unwrap(),430		);431		assert_eq!(432			<TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE433				.as_str()434				.unwrap(),435			<TupleStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE436				.as_str()437				.unwrap(),438		);439		assert_eq!(440			<TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::SIGNATURE441				.as_str()442				.unwrap(),443			<TupleStruct3DerivedMixedParam as evm_coder::abi::AbiType>::SIGNATURE444				.as_str()445				.unwrap(),446		);447	}448449	#[test]450	fn impl_abi_type_is_dynamic_same_for_structs() {451		assert_eq!(452			<TypeStruct1SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),453			<TupleStruct1SimpleParam as evm_coder::abi::AbiType>::is_dynamic()454		);455		assert_eq!(456			<TypeStruct1DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),457			<TupleStruct1DynamicParam as evm_coder::abi::AbiType>::is_dynamic()458		);459		assert_eq!(460			<TypeStruct2SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),461			<TupleStruct2SimpleParam as evm_coder::abi::AbiType>::is_dynamic()462		);463		assert_eq!(464			<TypeStruct2DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),465			<TupleStruct2DynamicParam as evm_coder::abi::AbiType>::is_dynamic()466		);467		assert_eq!(468			<TypeStruct2MixedParam as evm_coder::abi::AbiType>::is_dynamic(),469			<TupleStruct2MixedParam as evm_coder::abi::AbiType>::is_dynamic()470		);471		assert_eq!(472			<TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),473			<TupleStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic()474		);475		assert_eq!(476			<TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),477			<TupleStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic()478		);479		assert_eq!(480			<TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),481			<TupleStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic()482		);483		assert_eq!(484			<TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),485			<TupleStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic()486		);487		assert_eq!(488			<TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::is_dynamic(),489			<TupleStruct3DerivedMixedParam as evm_coder::abi::AbiType>::is_dynamic()490		);491	}492493	#[test]494	fn impl_abi_type_size_same_for_structs() {495		assert_eq!(496			<TypeStruct1SimpleParam as evm_coder::abi::AbiType>::size(),497			<TupleStruct1SimpleParam as evm_coder::abi::AbiType>::size()498		);499		assert_eq!(500			<TypeStruct1DynamicParam as evm_coder::abi::AbiType>::size(),501			<TupleStruct1DynamicParam as evm_coder::abi::AbiType>::size()502		);503		assert_eq!(504			<TypeStruct2SimpleParam as evm_coder::abi::AbiType>::size(),505			<TupleStruct2SimpleParam as evm_coder::abi::AbiType>::size()506		);507		assert_eq!(508			<TypeStruct2DynamicParam as evm_coder::abi::AbiType>::size(),509			<TupleStruct2DynamicParam as evm_coder::abi::AbiType>::size()510		);511		assert_eq!(512			<TypeStruct2MixedParam as evm_coder::abi::AbiType>::size(),513			<TupleStruct2MixedParam as evm_coder::abi::AbiType>::size()514		);515		assert_eq!(516			<TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::size(),517			<TupleStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::size()518		);519		assert_eq!(520			<TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::size(),521			<TupleStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::size()522		);523		assert_eq!(524			<TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::size(),525			<TupleStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::size()526		);527		assert_eq!(528			<TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::size(),529			<TupleStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::size()530		);531		assert_eq!(532			<TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::size(),533			<TupleStruct3DerivedMixedParam as evm_coder::abi::AbiType>::size()534		);535	}536537	const FUNCTION_IDENTIFIER: u32 = 0xdeadbeef;538539	fn test_impl<Tuple, TupleStruct, TypeStruct>(540		tuple_data: Tuple,541		tuple_struct_data: TupleStruct,542		type_struct_data: TypeStruct,543	) where544		TypeStruct: evm_coder::abi::AbiWrite545			+ evm_coder::abi::AbiRead546			+ std::cmp::PartialEq547			+ std::fmt::Debug,548		TupleStruct: evm_coder::abi::AbiWrite549			+ evm_coder::abi::AbiRead550			+ std::cmp::PartialEq551			+ std::fmt::Debug,552		Tuple: evm_coder::abi::AbiWrite553			+ evm_coder::abi::AbiRead554			+ std::cmp::PartialEq555			+ std::fmt::Debug,556	{557		let encoded_type_struct = test_abi_write_impl(&type_struct_data);558		let encoded_tuple_struct = test_abi_write_impl(&tuple_struct_data);559		let encoded_tuple = test_abi_write_impl(&tuple_data);560561		similar_asserts::assert_eq!(encoded_tuple, encoded_type_struct);562		similar_asserts::assert_eq!(encoded_tuple, encoded_tuple_struct);563564		{565			let (_, mut decoder) = evm_coder::abi::AbiReader::new_call(&encoded_tuple).unwrap();566			let restored_struct_data = <TypeStruct>::abi_read(&mut decoder).unwrap();567			assert_eq!(restored_struct_data, type_struct_data);568		}569		{570			let (_, mut decoder) = evm_coder::abi::AbiReader::new_call(&encoded_tuple).unwrap();571			let restored_struct_data = <TupleStruct>::abi_read(&mut decoder).unwrap();572			assert_eq!(restored_struct_data, tuple_struct_data);573		}574575		{576			let (_, mut decoder) =577				evm_coder::abi::AbiReader::new_call(&encoded_type_struct).unwrap();578			let restored_tuple_data = <Tuple>::abi_read(&mut decoder).unwrap();579			assert_eq!(restored_tuple_data, tuple_data);580		}581		{582			let (_, mut decoder) =583				evm_coder::abi::AbiReader::new_call(&encoded_tuple_struct).unwrap();584			let restored_tuple_data = <Tuple>::abi_read(&mut decoder).unwrap();585			assert_eq!(restored_tuple_data, tuple_data);586		}587	}588589	fn test_abi_write_impl<A>(data: &A) -> Vec<u8>590	where591		A: evm_coder::abi::AbiWrite592			+ evm_coder::abi::AbiRead593			+ std::cmp::PartialEq594			+ std::fmt::Debug,595	{596		let mut writer = evm_coder::abi::AbiWriter::new_call(FUNCTION_IDENTIFIER);597		data.abi_write(&mut writer);598		let encoded_tuple = writer.finish();599		encoded_tuple600	}601602	#[test]603	fn codec_struct_1_simple() {604		let _a = 0xff;605		test_impl::<(u8,), TupleStruct1SimpleParam, TypeStruct1SimpleParam>(606			(_a,),607			TupleStruct1SimpleParam(_a),608			TypeStruct1SimpleParam { _a },609		);610	}611612	#[test]613	fn codec_struct_1_dynamic() {614		let _a: String = "some string".into();615		test_impl::<(String,), TupleStruct1DynamicParam, TypeStruct1DynamicParam>(616			(_a.clone(),),617			TupleStruct1DynamicParam(_a.clone()),618			TypeStruct1DynamicParam { _a },619		);620	}621622	#[test]623	fn codec_struct_1_derived_simple() {624		let _a: u8 = 0xff;625		test_impl::<((u8,),), TupleStruct1DerivedSimpleParam, TypeStruct1DerivedSimpleParam>(626			((_a,),),627			TupleStruct1DerivedSimpleParam(TupleStruct1SimpleParam(_a)),628			TypeStruct1DerivedSimpleParam {629				_a: TypeStruct1SimpleParam { _a },630			},631		);632	}633634	#[test]635	fn codec_struct_1_derived_dynamic() {636		let _a: String = "some string".into();637		test_impl::<((String,),), TupleStruct1DerivedDynamicParam, TypeStruct1DerivedDynamicParam>(638			((_a.clone(),),),639			TupleStruct1DerivedDynamicParam(TupleStruct1DynamicParam(_a.clone())),640			TypeStruct1DerivedDynamicParam {641				_a: TypeStruct1DynamicParam { _a },642			},643		);644	}645646	#[test]647	fn codec_struct_2_simple() {648		let _a = 0xff;649		let _b = 0xbeefbaba;650		test_impl::<(u8, u32), TupleStruct2SimpleParam, TypeStruct2SimpleParam>(651			(_a, _b),652			TupleStruct2SimpleParam(_a, _b),653			TypeStruct2SimpleParam { _a, _b },654		);655	}656657	#[test]658	fn codec_struct_2_dynamic() {659		let _a: String = "some string".into();660		let _b: bytes = bytes(vec![0x11, 0x22, 0x33]);661		test_impl::<(String, bytes), TupleStruct2DynamicParam, TypeStruct2DynamicParam>(662			(_a.clone(), _b.clone()),663			TupleStruct2DynamicParam(_a.clone(), _b.clone()),664			TypeStruct2DynamicParam { _a, _b },665		);666	}667668	#[test]669	fn codec_struct_2_mixed() {670		let _a: u8 = 0xff;671		let _b: bytes = bytes(vec![0x11, 0x22, 0x33]);672		test_impl::<(u8, bytes), TupleStruct2MixedParam, TypeStruct2MixedParam>(673			(_a.clone(), _b.clone()),674			TupleStruct2MixedParam(_a.clone(), _b.clone()),675			TypeStruct2MixedParam { _a, _b },676		);677	}678679	#[test]680	fn codec_struct_2_derived_simple() {681		let _a = 0xff;682		let _b = 0xbeefbaba;683		test_impl::<684			((u8,), (u8, u32)),685			TupleStruct2DerivedSimpleParam,686			TypeStruct2DerivedSimpleParam,687		>(688			((_a,), (_a, _b)),689			TupleStruct2DerivedSimpleParam(690				TupleStruct1SimpleParam(_a),691				TupleStruct2SimpleParam(_a, _b),692			),693			TypeStruct2DerivedSimpleParam {694				_a: TypeStruct1SimpleParam { _a },695				_b: TypeStruct2SimpleParam { _a, _b },696			},697		);698	}699700	#[test]701	fn codec_struct_2_derived_dynamic() {702		let _a = "some string".to_string();703		let _b = bytes(vec![0x11, 0x22, 0x33]);704		test_impl::<705			((String,), (String, bytes)),706			TupleStruct2DerivedDynamicParam,707			TypeStruct2DerivedDynamicParam,708		>(709			((_a.clone(),), (_a.clone(), _b.clone())),710			TupleStruct2DerivedDynamicParam(711				TupleStruct1DynamicParam(_a.clone()),712				TupleStruct2DynamicParam(_a.clone(), _b.clone()),713			),714			TypeStruct2DerivedDynamicParam {715				_a: TypeStruct1DynamicParam { _a: _a.clone() },716				_b: TypeStruct2DynamicParam { _a, _b },717			},718		);719	}720721	#[test]722	fn codec_struct_3_derived_mixed() {723		let int = 0xff;724		let by = bytes(vec![0x11, 0x22, 0x33]);725		let string = "some string".to_string();726		test_impl::<727			((u8,), (String, bytes), (u8, bytes)),728			TupleStruct3DerivedMixedParam,729			TypeStruct3DerivedMixedParam,730		>(731			((int,), (string.clone(), by.clone()), (int, by.clone())),732			TupleStruct3DerivedMixedParam(733				TupleStruct1SimpleParam(int),734				TupleStruct2DynamicParam(string.clone(), by.clone()),735				TupleStruct2MixedParam(int, by.clone()),736			),737			TypeStruct3DerivedMixedParam {738				_a: TypeStruct1SimpleParam { _a: int },739				_b: TypeStruct2DynamicParam {740					_a: string.clone(),741					_b: by.clone(),742				},743				_c: TypeStruct2MixedParam { _a: int, _b: by },744			},745		);746	}747748	#[derive(AbiCoder, PartialEq, Debug)]749	struct TypeStruct2SimpleStruct1Simple {750		_a: TypeStruct2SimpleParam,751		_b: TypeStruct2SimpleParam,752		_c: u8,753	}754	#[derive(AbiCoder, PartialEq, Debug)]755	struct TupleStruct2SimpleStruct1Simple(TupleStruct2SimpleParam, TupleStruct2SimpleParam, u8);756757	#[test]758	fn codec_struct_2_struct_simple_1_simple() {759		let _a = 0xff;760		let _b = 0xbeefbaba;761		test_impl::<762			((u8, u32), (u8, u32), u8),763			TupleStruct2SimpleStruct1Simple,764			TypeStruct2SimpleStruct1Simple,765		>(766			((_a, _b), (_a, _b), _a),767			TupleStruct2SimpleStruct1Simple(768				TupleStruct2SimpleParam(_a, _b),769				TupleStruct2SimpleParam(_a, _b),770				_a,771			),772			TypeStruct2SimpleStruct1Simple {773				_a: TypeStruct2SimpleParam { _a, _b },774				_b: TypeStruct2SimpleParam { _a, _b },775				_c: _a,776			},777		);778	}779}780781mod test_enum {782	use evm_coder::AbiCoder;783784	/// Some docs785	/// At multi786	/// line787	#[derive(AbiCoder, Debug, PartialEq, Default, Clone, Copy)]788	#[repr(u8)]789	enum Color {790		/// Docs for Red791		/// multi792		/// line793		Red,794		Green,795		/// Docs for Blue796		#[default]797		Blue,798	}799800	#[test]801	fn empty() {}802803	#[test]804	fn bad_enums() {805		let t = trybuild::TestCases::new();806		t.compile_fail("tests/build_failed/abi_derive_enum_generation.rs");807	}808809	#[test]810	fn impl_abi_type_signature_same_for_structs() {811		assert_eq!(812			<Color as evm_coder::abi::AbiType>::SIGNATURE813				.as_str()814				.unwrap(),815			<u8 as evm_coder::abi::AbiType>::SIGNATURE.as_str().unwrap()816		);817	}818819	#[test]820	fn impl_abi_type_is_dynamic_same_for_structs() {821		assert_eq!(822			<Color as evm_coder::abi::AbiType>::is_dynamic(),823			<u8 as evm_coder::abi::AbiType>::is_dynamic()824		);825	}826827	#[test]828	fn impl_abi_type_size_same_for_structs() {829		assert_eq!(830			<Color as evm_coder::abi::AbiType>::size(),831			<u8 as evm_coder::abi::AbiType>::size()832		);833	}834835	#[test]836	fn test_coder() {837		const FUNCTION_IDENTIFIER: u32 = 0xdeadbeef;838839		let encoded_enum = {840			let mut writer = evm_coder::abi::AbiWriter::new_call(FUNCTION_IDENTIFIER);841			<Color as evm_coder::abi::AbiWrite>::abi_write(&Color::Green, &mut writer);842			writer.finish()843		};844845		let encoded_u8 = {846			let mut writer = evm_coder::abi::AbiWriter::new_call(FUNCTION_IDENTIFIER);847			<u8 as evm_coder::abi::AbiWrite>::abi_write(&(Color::Green as u8), &mut writer);848			writer.finish()849		};850851		similar_asserts::assert_eq!(encoded_enum, encoded_u8);852853		{854			let (_, mut decoder) = evm_coder::abi::AbiReader::new_call(&encoded_enum).unwrap();855			let restored_enum_data =856				<Color as evm_coder::abi::AbiRead>::abi_read(&mut decoder).unwrap();857			assert_eq!(restored_enum_data, Color::Green);858		}859	}860861	#[test]862	#[cfg(feature = "stubgen")]863	fn struct_collect_enum() {864		assert_eq!(865			<Color as ::evm_coder::solidity::StructCollect>::name(),866			"Color"867		);868		similar_asserts::assert_eq!(869			<Color as ::evm_coder::solidity::StructCollect>::declaration(),870			r#"/// @dev Some docs871/// At multi872/// line873enum Color {874	/// @dev Docs for Red875	/// multi876	/// line877	Red,878	Green,879	/// @dev Docs for Blue880	Blue881}882"#883		);884	}885}