git.delta.rocks / unique-network / refs/commits / 3e03fdf5b91e

difftreelog

feat Implementations solidity traits to generate solidity code for macro AbiCoder

Trubnikov Sergey2022-11-21parent: #a16933b.patch.diff
in: master

3 files changed

modifiedcrates/evm-coder/procedural/src/abi_derive.rsdiffbeforeafterboth
--- a/crates/evm-coder/procedural/src/abi_derive.rs
+++ b/crates/evm-coder/procedural/src/abi_derive.rs
@@ -28,15 +28,25 @@
 
 	let can_be_plcaed_in_vec = impl_can_be_placed_in_vec(name);
 	let abi_type = impl_abi_type(name, field_types.clone());
-	let abi_read = impl_abi_read(name, is_named_fields, field_names.clone(), field_types);
-	let abi_write = impl_abi_write(name, is_named_fields, params_count, field_names);
-	// let solidity_tuple_type =
+	let abi_read = impl_abi_read(
+		name,
+		is_named_fields,
+		field_names.clone(),
+		field_types.clone(),
+	);
+	let abi_write = impl_abi_write(name, is_named_fields, params_count, field_names.clone());
+	let solidity_type = impl_solidity_type(name, field_types.clone(), params_count);
+	let solidity_type_name = impl_solidity_type_name(name, field_types.clone(), params_count);
+	let solidity_struct_collect = impl_solidity_struct_collect(name, field_names, field_types);
 
 	Ok(quote! {
 		#can_be_plcaed_in_vec
 		#abi_type
 		#abi_read
 		#abi_write
+		#solidity_type
+		#solidity_type_name
+		#solidity_struct_collect
 	})
 }
 
@@ -173,3 +183,112 @@
 		}
 	)
 }
+
+fn impl_solidity_type<'a>(
+	name: &syn::Ident,
+	field_types: impl Iterator<Item = &'a syn::Type> + Clone,
+	params_count: usize,
+) -> proc_macro2::TokenStream {
+	let len = proc_macro2::Literal::usize_suffixed(params_count);
+	quote! {
+		#[cfg(feature = "stubgen")]
+		impl ::evm_coder::solidity::SolidityType for #name {
+			fn names(tc: &::evm_coder::solidity::TypeCollector) -> Vec<String> {
+				let mut collected =
+					Vec::with_capacity(<Self as ::evm_coder::solidity::SolidityType>::len());
+				#({
+					let mut out = String::new();
+					<#field_types as ::evm_coder::solidity::SolidityTypeName>::solidity_name(&mut out, tc)
+						.expect("no fmt error");
+					collected.push(out);
+				})*
+				collected
+			}
+
+			fn len() -> usize {
+				#len
+			}
+		}
+	}
+}
+
+fn impl_solidity_type_name<'a>(
+	name: &syn::Ident,
+	field_types: impl Iterator<Item = &'a syn::Type> + Clone,
+	params_count: usize,
+) -> proc_macro2::TokenStream {
+	let arg_dafaults = field_types.enumerate().map(|(i, ty)| {
+		let mut defult_value = quote!(<#ty as ::evm_coder::solidity::SolidityTypeName
+			>::solidity_default(writer, tc)?;);
+		let last_item = params_count - 1;
+		if i != last_item {
+			defult_value.extend(quote! {write!(writer, ",")?;})
+		}
+		defult_value
+	});
+
+	quote! {
+		#[cfg(feature = "stubgen")]
+		impl ::evm_coder::solidity::SolidityTypeName for #name {
+			fn solidity_name(
+				writer: &mut impl ::core::fmt::Write,
+				tc: &::evm_coder::solidity::TypeCollector,
+			) -> ::core::fmt::Result {
+				write!(writer, "{}", tc.collect_struct::<Self>())
+			}
+
+			fn is_simple() -> bool {
+				false
+			}
+
+			fn solidity_default(
+				writer: &mut impl ::core::fmt::Write,
+				tc: &::evm_coder::solidity::TypeCollector,
+			) -> ::core::fmt::Result {
+				write!(writer, "{}(", tc.collect_struct::<Self>())?;
+
+				#(#arg_dafaults)*
+
+				write!(writer, ")")
+			}
+		}
+	}
+}
+
+fn impl_solidity_struct_collect<'a>(
+	name: &syn::Ident,
+	field_names: impl Iterator<Item = proc_macro2::Ident> + Clone,
+	field_types: impl Iterator<Item = &'a syn::Type> + Clone,
+) -> proc_macro2::TokenStream {
+	let string_name = name.to_string();
+	let name_type = field_names
+		.into_iter()
+		.zip(field_types.into_iter())
+		.map(|(name, ty)| {
+			let name = format!("{}", name);
+			quote!(
+				write!(str, "\t{} ", <#ty as ::evm_coder::solidity::StructCollect>::name()).unwrap();
+				write!(str, "{};", #name).unwrap();
+			)
+		});
+
+	quote! {
+		#[cfg(feature = "stubgen")]
+		impl ::evm_coder::solidity::StructCollect for #name {
+			fn name() -> String {
+				#string_name.into()
+			}
+
+			fn declaration() -> String {
+				use std::fmt::Write;
+
+				let mut str = String::new();
+				writeln!(str, "/// @dev Cross account struct").unwrap();
+				writeln!(str, "struct {} {{", Self::name()).unwrap();
+				#(#name_type)*
+				writeln!(str, "}}").unwrap();
+				str
+			}
+		}
+	}
+}
modifiedcrates/evm-coder/src/solidity/impls.rsdiffbeforeafterboth
before · crates/evm-coder/src/solidity/impls.rs
1use super::{TypeCollector, SolidityTypeName, SolidityType};2use crate::{sealed, types::*};3use core::fmt;45macro_rules! solidity_type_name {6    ($($ty:ty => $name:literal $simple:literal = $default:literal),* $(,)?) => {7        $(8            impl SolidityTypeName for $ty {9                fn solidity_name(writer: &mut impl core::fmt::Write, _tc: &TypeCollector) -> core::fmt::Result {10                    write!(writer, $name)11                }12				fn is_simple() -> bool {13					$simple14				}15				fn solidity_default(writer: &mut impl core::fmt::Write, _tc: &TypeCollector) -> core::fmt::Result {16					write!(writer, $default)17				}18            }19        )*20    };21}2223solidity_type_name! {24	uint8 => "uint8" true = "0",25	uint32 => "uint32" true = "0",26	uint64 => "uint64" true = "0",27	uint128 => "uint128" true = "0",28	uint256 => "uint256" true = "0",29	bytes4 => "bytes4" true = "bytes4(0)",30	address => "address" true = "0x0000000000000000000000000000000000000000",31	string => "string" false = "\"\"",32	bytes => "bytes" false = "hex\"\"",33	bool => "bool" true = "false",34}3536impl SolidityTypeName for void {37	fn solidity_name(_writer: &mut impl fmt::Write, _tc: &TypeCollector) -> fmt::Result {38		Ok(())39	}40	fn is_simple() -> bool {41		true42	}43	fn solidity_default(_writer: &mut impl fmt::Write, _tc: &TypeCollector) -> fmt::Result {44		Ok(())45	}46	fn is_void() -> bool {47		true48	}49}5051impl<T: SolidityTypeName + sealed::CanBePlacedInVec> SolidityTypeName for Vec<T> {52	fn solidity_name(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {53		T::solidity_name(writer, tc)?;54		write!(writer, "[]")55	}56	fn is_simple() -> bool {57		false58	}59	fn solidity_default(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {60		write!(writer, "new ")?;61		T::solidity_name(writer, tc)?;62		write!(writer, "[](0)")63	}64}6566macro_rules! count {67    () => (0usize);68    ( $x:tt $($xs:tt)* ) => (1usize + count!($($xs)*));69}7071macro_rules! impl_tuples {72	($($ident:ident)+) => {73		impl<$($ident: SolidityTypeName + 'static),+> SolidityType for ($($ident,)+) {74			fn names(tc: &TypeCollector) -> Vec<string> {75				let mut collected = Vec::with_capacity(Self::len());76				$({77					let mut out = string::new();78					$ident::solidity_name(&mut out, tc).expect("no fmt error");79					collected.push(out);80				})*;81				collected82			}8384			fn len() -> usize {85				count!($($ident)*)86			}87		}88		impl<$($ident: SolidityTypeName + 'static),+> SolidityTypeName for ($($ident,)+) {89			fn solidity_name(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {90				write!(writer, "{}", tc.collect_tuple::<Self>())91			}92			fn is_simple() -> bool {93				false94			}95			#[allow(unused_assignments)]96			fn solidity_default(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {97				write!(writer, "{}(", tc.collect_tuple::<Self>())?;98				let mut first = true;99				$(100					if !first {101						write!(writer, ",")?;102					} else {103						first = false;104					}105					<$ident>::solidity_default(writer, tc)?;106				)*107				write!(writer, ")")108			}109		}110	};111}112113impl_tuples! {A}114impl_tuples! {A B}115impl_tuples! {A B C}116impl_tuples! {A B C D}117impl_tuples! {A B C D E}118impl_tuples! {A B C D E F}119impl_tuples! {A B C D E F G}120impl_tuples! {A B C D E F G H}121impl_tuples! {A B C D E F G H I}122impl_tuples! {A B C D E F G H I J}123124impl sealed::CanBePlacedInVec for Property {}125impl StructCollect for Property {126	fn name() -> String {127		"Property".into()128	}129130	fn declaration() -> String {131		let mut str = String::new();132		writeln!(str, "/// @dev Property struct").unwrap();133		writeln!(str, "struct {} {{", Self::name()).unwrap();134		writeln!(str, "\tstring key;").unwrap();135		writeln!(str, "\tbytes value;").unwrap();136		writeln!(str, "}}").unwrap();137		str138	}139}140141impl SolidityTypeName for Property {142	fn solidity_name(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {143		write!(writer, "{}", tc.collect_struct::<Self>())144	}145146	fn is_simple() -> bool {147		false148	}149150	fn solidity_default(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {151		write!(writer, "{}(", tc.collect_struct::<Self>())?;152		address::solidity_default(writer, tc)?;153		write!(writer, ",")?;154		uint256::solidity_default(writer, tc)?;155		write!(writer, ")")156	}157}158159impl SolidityTupleType for Property {160	fn names(tc: &TypeCollector) -> Vec<string> {161		let mut collected = Vec::with_capacity(Self::len());162		{163			let mut out = string::new();164			string::solidity_name(&mut out, tc).expect("no fmt error");165			collected.push(out);166		}167		{168			let mut out = string::new();169			bytes::solidity_name(&mut out, tc).expect("no fmt error");170			collected.push(out);171		}172		collected173	}174175	fn len() -> usize {176		2177	}178}
after · crates/evm-coder/src/solidity/impls.rs
1use super::{TypeCollector, SolidityTypeName, SolidityType, StructCollect};2use crate::{sealed, types::*};3use core::fmt;45macro_rules! solidity_type_name {6    ($($ty:ty => $name:literal $simple:literal = $default:literal),* $(,)?) => {7        $(8            impl SolidityTypeName for $ty {9                fn solidity_name(writer: &mut impl core::fmt::Write, _tc: &TypeCollector) -> core::fmt::Result {10                    write!(writer, $name)11                }12				fn is_simple() -> bool {13					$simple14				}15				fn solidity_default(writer: &mut impl core::fmt::Write, _tc: &TypeCollector) -> core::fmt::Result {16					write!(writer, $default)17				}18            }1920			impl StructCollect for $ty {21				fn name() -> String {22					$name.to_string()23				}2425				fn declaration() -> String {26					String::default()27				}28			}29        )*30    };31}3233solidity_type_name! {34	uint8 => "uint8" true = "0",35	uint32 => "uint32" true = "0",36	uint64 => "uint64" true = "0",37	uint128 => "uint128" true = "0",38	uint256 => "uint256" true = "0",39	bytes4 => "bytes4" true = "bytes4(0)",40	address => "address" true = "0x0000000000000000000000000000000000000000",41	string => "string" false = "\"\"",42	bytes => "bytes" false = "hex\"\"",43	bool => "bool" true = "false",44}4546impl SolidityTypeName for void {47	fn solidity_name(_writer: &mut impl fmt::Write, _tc: &TypeCollector) -> fmt::Result {48		Ok(())49	}50	fn is_simple() -> bool {51		true52	}53	fn solidity_default(_writer: &mut impl fmt::Write, _tc: &TypeCollector) -> fmt::Result {54		Ok(())55	}56	fn is_void() -> bool {57		true58	}59}6061impl<T: SolidityTypeName + sealed::CanBePlacedInVec> SolidityTypeName for Vec<T> {62	fn solidity_name(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {63		T::solidity_name(writer, tc)?;64		write!(writer, "[]")65	}66	fn is_simple() -> bool {67		false68	}69	fn solidity_default(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {70		write!(writer, "new ")?;71		T::solidity_name(writer, tc)?;72		write!(writer, "[](0)")73	}74}7576macro_rules! count {77    () => (0usize);78    ( $x:tt $($xs:tt)* ) => (1usize + count!($($xs)*));79}8081macro_rules! impl_tuples {82	($($ident:ident)+) => {83		impl<$($ident: SolidityTypeName + 'static),+> SolidityType for ($($ident,)+) {84			fn names(tc: &TypeCollector) -> Vec<string> {85				let mut collected = Vec::with_capacity(Self::len());86				$({87					let mut out = string::new();88					$ident::solidity_name(&mut out, tc).expect("no fmt error");89					collected.push(out);90				})*;91				collected92			}9394			fn len() -> usize {95				count!($($ident)*)96			}97		}98		impl<$($ident: SolidityTypeName + 'static),+> SolidityTypeName for ($($ident,)+) {99			fn solidity_name(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {100				write!(writer, "{}", tc.collect_tuple::<Self>())101			}102			fn is_simple() -> bool {103				false104			}105			#[allow(unused_assignments)]106			fn solidity_default(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {107				write!(writer, "{}(", tc.collect_tuple::<Self>())?;108				let mut first = true;109				$(110					if !first {111						write!(writer, ",")?;112					} else {113						first = false;114					}115					<$ident>::solidity_default(writer, tc)?;116				)*117				write!(writer, ")")118			}119		}120	};121}122123impl_tuples! {A}124impl_tuples! {A B}125impl_tuples! {A B C}126impl_tuples! {A B C D}127impl_tuples! {A B C D E}128impl_tuples! {A B C D E F}129impl_tuples! {A B C D E F G}130impl_tuples! {A B C D E F G H}131impl_tuples! {A B C D E F G H I}132impl_tuples! {A B C D E F G H I J}133134impl sealed::CanBePlacedInVec for Property {}135impl StructCollect for Property {136	fn name() -> String {137		"Property".into()138	}139140	fn declaration() -> String {141		let mut str = String::new();142		writeln!(str, "/// @dev Property struct").unwrap();143		writeln!(str, "struct {} {{", Self::name()).unwrap();144		writeln!(str, "\tstring key;").unwrap();145		writeln!(str, "\tbytes value;").unwrap();146		writeln!(str, "}}").unwrap();147		str148	}149}150151impl SolidityTypeName for Property {152	fn solidity_name(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {153		write!(writer, "{}", tc.collect_struct::<Self>())154	}155156	fn is_simple() -> bool {157		false158	}159160	fn solidity_default(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {161		write!(writer, "{}(", tc.collect_struct::<Self>())?;162		address::solidity_default(writer, tc)?;163		write!(writer, ",")?;164		uint256::solidity_default(writer, tc)?;165		write!(writer, ")")166	}167}168169impl SolidityTupleType for Property {170	fn names(tc: &TypeCollector) -> Vec<string> {171		let mut collected = Vec::with_capacity(Self::len());172		{173			let mut out = string::new();174			string::solidity_name(&mut out, tc).expect("no fmt error");175			collected.push(out);176		}177		{178			let mut out = string::new();179			bytes::solidity_name(&mut out, tc).expect("no fmt error");180			collected.push(out);181		}182		collected183	}184185	fn len() -> usize {186		2187	}188}
modifiedpallets/common/src/eth.rsdiffbeforeafterboth
--- a/pallets/common/src/eth.rs
+++ b/pallets/common/src/eth.rs
@@ -154,72 +154,3 @@
 		}
 	}
 }
-
-#[cfg(feature = "stubgen")]
-impl ::evm_coder::solidity::SolidityType for EthCrossAccount {
-	fn names(tc: &::evm_coder::solidity::TypeCollector) -> Vec<String> {
-		let mut collected =
-			Vec::with_capacity(<Self as ::evm_coder::solidity::SolidityType>::len());
-		{
-			let mut out = String::new();
-			<address as ::evm_coder::solidity::SolidityTypeName>::solidity_name(&mut out, tc)
-				.expect("no fmt error");
-			collected.push(out);
-		}
-		{
-			let mut out = String::new();
-			<uint256 as ::evm_coder::solidity::SolidityTypeName>::solidity_name(&mut out, tc)
-				.expect("no fmt error");
-			collected.push(out);
-		}
-		collected
-	}
-
-	fn len() -> usize {
-		2
-	}
-}
-
-#[cfg(feature = "stubgen")]
-impl ::evm_coder::solidity::SolidityTypeName for EthCrossAccount {
-	fn solidity_name(
-		writer: &mut impl ::core::fmt::Write,
-		tc: &::evm_coder::solidity::TypeCollector,
-	) -> ::core::fmt::Result {
-		write!(writer, "{}", tc.collect_struct::<Self>())
-	}
-
-	fn is_simple() -> bool {
-		false
-	}
-
-	fn solidity_default(
-		writer: &mut impl ::core::fmt::Write,
-		tc: &::evm_coder::solidity::TypeCollector,
-	) -> ::core::fmt::Result {
-		write!(writer, "{}(", tc.collect_struct::<Self>())?;
-		address::solidity_default(writer, tc)?;
-		write!(writer, ",")?;
-		uint256::solidity_default(writer, tc)?;
-		write!(writer, ")")
-	}
-}
-
-#[cfg(feature = "stubgen")]
-impl ::evm_coder::solidity::StructCollect for EthCrossAccount {
-	fn name() -> String {
-		"EthCrossAccount".into()
-	}
-
-	fn declaration() -> String {
-		use std::fmt::Write;
-
-		let mut str = String::new();
-		writeln!(str, "/// @dev Cross account struct").unwrap();
-		writeln!(str, "struct {} {{", Self::name()).unwrap();
-		writeln!(str, "\taddress eth;").unwrap();
-		writeln!(str, "\tuint256 sub;").unwrap();
-		writeln!(str, "}}").unwrap();
-		str
-	}
-}