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
--- a/crates/evm-coder/src/solidity/impls.rs
+++ b/crates/evm-coder/src/solidity/impls.rs
@@ -1,4 +1,4 @@
-use super::{TypeCollector, SolidityTypeName, SolidityType};
+use super::{TypeCollector, SolidityTypeName, SolidityType, StructCollect};
 use crate::{sealed, types::*};
 use core::fmt;
 
@@ -16,6 +16,16 @@
 					write!(writer, $default)
 				}
             }
+
+			impl StructCollect for $ty {
+				fn name() -> String {
+					$name.to_string()
+				}
+
+				fn declaration() -> String {
+					String::default()
+				}
+			}
         )*
     };
 }
modifiedpallets/common/src/eth.rsdiffbeforeafterboth
155 }155 }
156}156}
157
158#[cfg(feature = "stubgen")]
159impl ::evm_coder::solidity::SolidityType for EthCrossAccount {
160 fn names(tc: &::evm_coder::solidity::TypeCollector) -> Vec<String> {
161 let mut collected =
162 Vec::with_capacity(<Self as ::evm_coder::solidity::SolidityType>::len());
163 {
164 let mut out = String::new();
165 <address as ::evm_coder::solidity::SolidityTypeName>::solidity_name(&mut out, tc)
166 .expect("no fmt error");
167 collected.push(out);
168 }
169 {
170 let mut out = String::new();
171 <uint256 as ::evm_coder::solidity::SolidityTypeName>::solidity_name(&mut out, tc)
172 .expect("no fmt error");
173 collected.push(out);
174 }
175 collected
176 }
177
178 fn len() -> usize {
179 2
180 }
181}
182
183#[cfg(feature = "stubgen")]
184impl ::evm_coder::solidity::SolidityTypeName for EthCrossAccount {
185 fn solidity_name(
186 writer: &mut impl ::core::fmt::Write,
187 tc: &::evm_coder::solidity::TypeCollector,
188 ) -> ::core::fmt::Result {
189 write!(writer, "{}", tc.collect_struct::<Self>())
190 }
191
192 fn is_simple() -> bool {
193 false
194 }
195
196 fn solidity_default(
197 writer: &mut impl ::core::fmt::Write,
198 tc: &::evm_coder::solidity::TypeCollector,
199 ) -> ::core::fmt::Result {
200 write!(writer, "{}(", tc.collect_struct::<Self>())?;
201 address::solidity_default(writer, tc)?;
202 write!(writer, ",")?;
203 uint256::solidity_default(writer, tc)?;
204 write!(writer, ")")
205 }
206}
207
208#[cfg(feature = "stubgen")]
209impl ::evm_coder::solidity::StructCollect for EthCrossAccount {
210 fn name() -> String {
211 "EthCrossAccount".into()
212 }
213
214 fn declaration() -> String {
215 use std::fmt::Write;
216
217 let mut str = String::new();
218 writeln!(str, "/// @dev Cross account struct").unwrap();
219 writeln!(str, "struct {} {{", Self::name()).unwrap();
220 writeln!(str, "\taddress eth;").unwrap();
221 writeln!(str, "\tuint256 sub;").unwrap();
222 writeln!(str, "}}").unwrap();
223 str
224 }
225}
226157