difftreelog
feat solidity code generation
in: master
2 files changed
crates/evm-coder-macros/src/solidity_interface.rsdiffbeforeafterboth6use 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};8119use crate::{12use crate::{164 }167 }165 }168 }169170 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}167178168#[derive(PartialEq)]179#[derive(PartialEq)]377 }388 }378 }389 }390391 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;399400 let args = self.args.iter().map(MethodArg::expand_solidity_argument);401402 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}380416381pub 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;405441442 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;408445436 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);439477440 // let methods = self.methods.iter().map(Method::solidity_def);478 // let methods = self.methods.iter().map(Method::solidity_def);441479467 )*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 out520 }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>> {crates/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