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
1#[cfg(not(feature = "std"))]
2use alloc::{string::String};
1use core::{fmt, marker::PhantomData};3use core::{fmt, marker::PhantomData};
2use impl_trait_for_tuples::impl_for_tuples;4use impl_trait_for_tuples::impl_for_tuples;
3use crate::types::*;5use crate::types::*;
2325
24solidity_type_name! {26solidity_type_name! {
25 uint8 => "uint8",27 uint8 => "uint8",
28 uint32 => "uint32",
29 uint128 => "uint128",
30 uint256 => "uint256",
26 address => "address",31 address => "address",
27 string => "memory string",32 string => "memory string",
33 bytes => "memory bytes",
34 bool => "bool",
28}35}
29impl SolidityTypeName for void {36impl SolidityTypeName for void {
30 fn solidity_name(_writer: &mut impl fmt::Write) -> fmt::Result {37 fn solidity_name(_writer: &mut impl fmt::Write) -> fmt::Result {
43 fn len(&self) -> usize;50 fn len(&self) -> usize;
44}51}
4552
53#[derive(Default)]
46pub struct UnnamedArgument<T>(PhantomData<*const T>);54pub struct UnnamedArgument<T>(PhantomData<*const T>);
4755
48impl<T: SolidityTypeName> SolidityArguments for UnnamedArgument<T> {56impl<T: SolidityTypeName> SolidityArguments for UnnamedArgument<T> {
6472
65pub struct NamedArgument<T>(&'static str, PhantomData<*const T>);73pub struct NamedArgument<T>(&'static str, PhantomData<*const T>);
74
75impl<T> NamedArgument<T> {
76 pub fn new(name: &'static str) -> Self {
77 Self(name, Default::default())
78 }
79}
6680
67impl<T: SolidityTypeName> SolidityArguments for NamedArgument<T> {81impl<T: SolidityTypeName> SolidityArguments for NamedArgument<T> {
68 fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result {82 fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result {
96 for_tuples!( where #( Tuple: SolidityArguments ),* );110 for_tuples!( where #( Tuple: SolidityArguments ),* );
97111
98 fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result {112 fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result {
99 let mut first = false;113 let mut first = true;
100 for_tuples!( #(114 for_tuples!( #(
101 if !Tuple.is_empty() {115 if !Tuple.is_empty() {
102 if first {116 if !first {
103 write!(writer, ", ")?;117 write!(writer, ", ")?;
104 }118 }
105 first = false;119 first = false;
113 }127 }
114}128}
115129
116trait SolidityFunctions {130pub trait SolidityFunctions {
117 fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result;131 fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result;
118}132}
119133
123 Mutable,137 Mutable,
124}138}
125pub struct SolidityFunction<A, R> {139pub struct SolidityFunction<A, R> {
126 name: &'static str,140 pub name: &'static str,
127 args: A,141 pub args: A,
128 result: R,142 pub result: R,
129 mutability: SolidityMutability,143 pub mutability: SolidityMutability,
130}144}
131impl<A: SolidityArguments, R: SolidityArguments> SolidityFunctions for SolidityFunction<A, R> {145impl<A: SolidityArguments, R: SolidityArguments> SolidityFunctions for SolidityFunction<A, R> {
132 fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result {146 fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result {
133 write!(writer, "function {}(", self.name)?;147 write!(writer, "function {}(", self.name)?;
134 self.args.solidity_name(writer)?;148 self.args.solidity_name(writer)?;
135 write!(writer, ") public")?;149 write!(writer, ") external")?;
136 match &self.mutability {150 match &self.mutability {
137 SolidityMutability::Pure => write!(writer, " pure")?,151 SolidityMutability::Pure => write!(writer, " pure")?,
138 SolidityMutability::View => write!(writer, " view")?,152 SolidityMutability::View => write!(writer, " view")?,
139 SolidityMutability::Mutable => {}153 SolidityMutability::Mutable => {}
140 }154 }
141 if !self.result.is_empty() {155 if !self.result.is_empty() {
142 write!(writer, "returns (")?;156 write!(writer, " returns (")?;
143 self.result.solidity_name(writer)?;157 self.result.solidity_name(writer)?;
144 write!(writer, ")")?;158 write!(writer, ")")?;
145 }159 }
160 }174 }
161}175}
162176
177pub struct SolidityInterface<F: SolidityFunctions> {
178 pub name: &'static str,
179 pub functions: F,
180}
181
182impl<F: SolidityFunctions> SolidityInterface<F> {
183 pub fn format(&self, out: &mut impl fmt::Write) -> fmt::Result {
184 writeln!(out, "interface {} {{", self.name)?;
185 self.functions.solidity_name(out)?;
186 writeln!(out, "}}")?;
187 Ok(())
188 }
189}