git.delta.rocks / unique-network / refs/commits / dc753ac3eb78

difftreelog

feat solidity code generation

Yaroslav Bolyukin2021-07-22parent: #ab49fc9.patch.diff
in: master

2 files changed

modifiedcrates/evm-coder-macros/src/solidity_interface.rsdiffbeforeafterboth
6use std::fmt::Write;6use std::fmt::Write;
7use syn::{FnArg, Generics, Ident, ImplItem, ImplItemMethod, ItemImpl, Meta, NestedMeta, PatType, Path, ReturnType, Type, spanned::Spanned};7use syn::{
8 FnArg, Generics, Ident, ImplItem, ImplItemMethod, ItemImpl, Meta, NestedMeta, PatType, Path,
9 ReturnType, Type, spanned::Spanned,
10};
811
9use crate::{12use crate::{
164 }167 }
165 }168 }
169
170 fn expand_solidity_argument(&self) -> proc_macro2::TokenStream {
171 let name = &self.name.to_string();
172 let ty = &self.ty;
173 quote! {
174 <NamedArgument<#ty>>::new(#name)
175 }
176 }
166}177}
167178
168#[derive(PartialEq)]179#[derive(PartialEq)]
377 }388 }
378 }389 }
390
391 fn expand_solidity_function(&self) -> proc_macro2::TokenStream {
392 let camel_name = &self.camel_name;
393 let mutability = match self.mutability {
394 Mutability::Mutable => quote! {SolidityMutability::Mutable},
395 Mutability::View => quote! { SolidityMutability::View },
396 Mutability::Pure => quote! {SolidityMutability::Pure},
397 };
398 let result = &self.result;
399
400 let args = self.args.iter().map(MethodArg::expand_solidity_argument);
401
402 quote! {
403 SolidityFunction {
404 name: #camel_name,
405 mutability: #mutability,
406 args: (
407 #(
408 #args,
409 )*
410 ),
411 result: <UnnamedArgument<#result>>::default(),
412 }
413 }
414 }
379}415}
380416
381pub struct SolidityInterface {417pub struct SolidityInterface {
403 pub fn expand(self) -> proc_macro2::TokenStream {439 pub fn expand(self) -> proc_macro2::TokenStream {
404 let name = self.name;440 let name = self.name;
405441
442 let solidity_name = self.info.name.to_string();
406 let call_name = pascal_ident_to_call(&self.info.name);443 let call_name = pascal_ident_to_call(&self.info.name);
407 let generics = self.generics;444 let generics = self.generics;
408445
436 let interface_id = self.methods.iter().map(Method::expand_interface_id);473 let interface_id = self.methods.iter().map(Method::expand_interface_id);
437 let parsers = self.methods.iter().map(Method::expand_parse);474 let parsers = self.methods.iter().map(Method::expand_parse);
438 let call_variants_this = self.methods.iter().map(Method::expand_variant_call);475 let call_variants_this = self.methods.iter().map(Method::expand_variant_call);
476 let solidity_functions = self.methods.iter().map(Method::expand_solidity_function);
439477
440 // let methods = self.methods.iter().map(Method::solidity_def);478 // let methods = self.methods.iter().map(Method::solidity_def);
441479
467 )*505 )*
468 )506 )
469 }507 }
508 pub fn generate_solidity_interface() -> string {
509 use evm_coder::solidity::*;
510 use core::fmt::Write;
511 let interface = SolidityInterface {
512 name: #solidity_name,
513 functions: (#(
514 #solidity_functions,
515 )*),
516 };
517 let mut out = string::new();
518 let _ = interface.format(&mut out);
519 out
520 }
470 }521 }
471 impl ::evm_coder::Call for #call_name {522 impl ::evm_coder::Call for #call_name {
472 fn parse(method_id: u32, reader: &mut ::evm_coder::abi::AbiReader) -> ::evm_coder::execution::Result<Option<Self>> {523 fn parse(method_id: u32, reader: &mut ::evm_coder::abi::AbiReader) -> ::evm_coder::execution::Result<Option<Self>> {
modifiedcrates/evm-coder/src/solidity.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/solidity.rs
+++ b/crates/evm-coder/src/solidity.rs
@@ -1,3 +1,5 @@
+#[cfg(not(feature = "std"))]
+use alloc::{string::String};
 use core::{fmt, marker::PhantomData};
 use impl_trait_for_tuples::impl_for_tuples;
 use crate::types::*;
@@ -23,8 +25,13 @@
 
 solidity_type_name! {
 	uint8 => "uint8",
+	uint32 => "uint32",
+	uint128 => "uint128",
+	uint256 => "uint256",
 	address => "address",
 	string => "memory string",
+	bytes => "memory bytes",
+	bool => "bool",
 }
 impl SolidityTypeName for void {
 	fn solidity_name(_writer: &mut impl fmt::Write) -> fmt::Result {
@@ -43,6 +50,7 @@
 	fn len(&self) -> usize;
 }
 
+#[derive(Default)]
 pub struct UnnamedArgument<T>(PhantomData<*const T>);
 
 impl<T: SolidityTypeName> SolidityArguments for UnnamedArgument<T> {
@@ -64,6 +72,12 @@
 
 pub struct NamedArgument<T>(&'static str, PhantomData<*const T>);
 
+impl<T> NamedArgument<T> {
+	pub fn new(name: &'static str) -> Self {
+		Self(name, Default::default())
+	}
+}
+
 impl<T: SolidityTypeName> SolidityArguments for NamedArgument<T> {
 	fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result {
 		if !T::is_void() {
@@ -96,10 +110,10 @@
 	for_tuples!( where #( Tuple: SolidityArguments ),* );
 
 	fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result {
-		let mut first = false;
+		let mut first = true;
 		for_tuples!( #(
             if !Tuple.is_empty() {
-                if first {
+                if !first {
                     write!(writer, ", ")?;
                 }
                 first = false;
@@ -113,7 +127,7 @@
 	}
 }
 
-trait SolidityFunctions {
+pub trait SolidityFunctions {
 	fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result;
 }
 
@@ -123,23 +137,23 @@
 	Mutable,
 }
 pub struct SolidityFunction<A, R> {
-	name: &'static str,
-	args: A,
-	result: R,
-	mutability: SolidityMutability,
+	pub name: &'static str,
+	pub args: A,
+	pub result: R,
+	pub mutability: SolidityMutability,
 }
 impl<A: SolidityArguments, R: SolidityArguments> SolidityFunctions for SolidityFunction<A, R> {
 	fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result {
 		write!(writer, "function {}(", self.name)?;
 		self.args.solidity_name(writer)?;
-		write!(writer, ") public")?;
+		write!(writer, ") external")?;
 		match &self.mutability {
 			SolidityMutability::Pure => write!(writer, " pure")?,
 			SolidityMutability::View => write!(writer, " view")?,
 			SolidityMutability::Mutable => {}
 		}
 		if !self.result.is_empty() {
-			write!(writer, "returns (")?;
+			write!(writer, " returns (")?;
 			self.result.solidity_name(writer)?;
 			write!(writer, ")")?;
 		}
@@ -159,3 +173,17 @@
 		Ok(())
 	}
 }
+
+pub struct SolidityInterface<F: SolidityFunctions> {
+	pub name: &'static str,
+	pub functions: F,
+}
+
+impl<F: SolidityFunctions> SolidityInterface<F> {
+	pub fn format(&self, out: &mut impl fmt::Write) -> fmt::Result {
+		writeln!(out, "interface {} {{", self.name)?;
+		self.functions.solidity_name(out)?;
+		writeln!(out, "}}")?;
+		Ok(())
+	}
+}
\ No newline at end of file