difftreelog
refactor impl AbiType, AbiWrite, AbiRead via tuple
in: master
3 files changed
crates/evm-coder/procedural/src/abi_derive.rsdiffbeforeafterboth1use proc_macro2::TokenStream;1use quote::quote;2use quote::quote;233pub(crate) fn impl_abi_macro(ast: &syn::DeriveInput) -> syn::Result<proc_macro2::TokenStream> {4pub(crate) fn impl_abi_macro(ast: &syn::DeriveInput) -> syn::Result<proc_macro2::TokenStream> {30 return Err(syn::Error::new(name.span(), "Empty structs not supported"));31 return Err(syn::Error::new(name.span(), "Empty structs not supported"));31 };32 };3334 let tuple_type = tuple_type(field_types.clone());35 let tuple_ref_type = tuple_ref_type(field_types.clone());36 let tuple_data = tuple_data_as_ref(is_named_fields, field_names.clone());37 let tuple_names = tuple_names(is_named_fields, field_names.clone());38 let struct_from_tuple = struct_from_tuple(name, is_named_fields, field_names.clone());323933 let can_be_plcaed_in_vec = impl_can_be_placed_in_vec(name);40 let can_be_plcaed_in_vec = impl_can_be_placed_in_vec(name);34 let abi_type = impl_abi_type(name, field_types.clone());41 let abi_type = impl_abi_type(name, tuple_type.clone());35 let abi_read = impl_abi_read(42 let abi_read = impl_abi_read(36 name,43 name,37 is_named_fields,38 field_names.clone(),44 tuple_type.clone(),39 field_types.clone(),45 tuple_names.clone(),46 struct_from_tuple,40 );47 );41 let abi_write = impl_abi_write(name, is_named_fields, params_count, field_names.clone());48 let abi_write = impl_abi_write(name, is_named_fields, tuple_ref_type, tuple_data);49 println!(50 "=========================\n{}\n=========================",51 &abi_write52 );42 let solidity_type = impl_solidity_type(name, field_types.clone(), params_count);53 let solidity_type = impl_solidity_type(name, field_types.clone(), params_count);43 let solidity_type_name = impl_solidity_type_name(name, field_types.clone(), params_count);54 let solidity_type_name = impl_solidity_type_name(name, field_types.clone(), params_count);44 let solidity_struct_collect =55 let solidity_struct_collect =55 })66 })56}67}6869fn tuple_type<'a>(70 field_types: impl Iterator<Item = &'a syn::Type> + Clone,71) -> proc_macro2::TokenStream {72 let field_types = field_types.map(|ty| quote!(#ty,));73 quote! {(#(#field_types)*)}74}75fn tuple_ref_type<'a>(76 field_types: impl Iterator<Item = &'a syn::Type> + Clone,77) -> proc_macro2::TokenStream {78 let field_types = field_types.map(|ty| quote!(&#ty,));79 quote! {(#(#field_types)*)}80}81fn tuple_data_as_ref(82 is_named_fields: bool,83 field_names: impl Iterator<Item = syn::Ident> + Clone,84) -> proc_macro2::TokenStream {85 let field_names = field_names.enumerate().map(|(i, field)| {86 if is_named_fields {87 quote!(&self.#field,)88 } else {89 let field = proc_macro2::Literal::usize_unsuffixed(i);90 quote!(&self.#field,)91 }92 });93 quote! {(#(#field_names)*)}94}95fn tuple_names(96 is_named_fields: bool,97 field_names: impl Iterator<Item = syn::Ident> + Clone,98) -> proc_macro2::TokenStream {99 let field_names = field_names.enumerate().map(|(i, field)| {100 if is_named_fields {101 quote!(#field,)102 } else {103 let field = proc_macro2::Ident::new(104 format!("field{}", i).as_str(),105 proc_macro2::Span::call_site(),106 );107 quote!(#field,)108 }109 });110 quote! {(#(#field_names)*)}111}112fn struct_from_tuple(113 name: &syn::Ident,114 is_named_fields: bool,115 field_names: impl Iterator<Item = syn::Ident> + Clone,116) -> proc_macro2::TokenStream {117 let field_names = field_names.enumerate().map(|(i, field)| {118 if is_named_fields {119 quote!(#field,)120 } else {121 let field = proc_macro2::Ident::new(122 format!("field{}", i).as_str(),123 proc_macro2::Span::call_site(),124 );125 quote!(#field,)126 }127 });128129 if is_named_fields {130 quote! {#name {#(#field_names)*}}131 } else {132 quote! {#name (#(#field_names)*)}133 }134}5713558fn extract_docs(attrs: &Vec<syn::Attribute>) -> syn::Result<Vec<String>> {136fn extract_docs(attrs: &Vec<syn::Attribute>) -> syn::Result<Vec<String>> {59 attrs137 attrs106184107fn impl_abi_type<'a>(185fn impl_abi_type<'a>(108 name: &syn::Ident,186 name: &syn::Ident,109 field_types: impl Iterator<Item = &'a syn::Type> + Clone,187 tuple_type: proc_macro2::TokenStream,110) -> proc_macro2::TokenStream {188) -> proc_macro2::TokenStream {111 let mut params_signature = {112 let types = field_types.clone();113 quote!(114 #(nameof(<#types as ::evm_coder::abi::AbiType>::SIGNATURE) fixed(","))*115 )116 };117118 params_signature.extend(quote!(shift_left(1)));119120 let fields_for_dynamic = field_types.clone();121122 quote! {189 quote! {123 impl ::evm_coder::abi::AbiType for #name {190 impl ::evm_coder::abi::AbiType for #name {124 const SIGNATURE: ::evm_coder::custom_signature::SignatureUnit = ::evm_coder::make_signature!(191 const SIGNATURE: ::evm_coder::custom_signature::SignatureUnit = <#tuple_type as ::evm_coder::abi::AbiType>::SIGNATURE;125 new fixed("(")126 #params_signature127 fixed(")")128 );129 fn is_dynamic() -> bool {192 fn is_dynamic() -> bool {130 false131 #(132 || <#fields_for_dynamic as ::evm_coder::abi::AbiType>::is_dynamic()193 <#tuple_type as ::evm_coder::abi::AbiType>::is_dynamic()133 )*134 }194 }135 fn size() -> usize {195 fn size() -> usize {136 0 #(+ <#field_types as ::evm_coder::abi::AbiType>::size())*196 <#tuple_type as ::evm_coder::abi::AbiType>::size()137 }197 }138 }198 }139 }199 }140}200}141201142fn impl_abi_read<'a>(202fn impl_abi_read<'a>(143 name: &syn::Ident,203 name: &syn::Ident,144 is_named_fields: bool,204 tuple_type: proc_macro2::TokenStream,145 field_names: impl Iterator<Item = proc_macro2::Ident> + Clone,205 tuple_names: proc_macro2::TokenStream,146 field_types: impl Iterator<Item = &'a syn::Type> + Clone,206 struct_from_tuple: proc_macro2::TokenStream,147) -> proc_macro2::TokenStream {207) -> proc_macro2::TokenStream {148 let field_names1 = field_names.clone();149150 let struct_constructor = if is_named_fields {151 quote!(Ok(Self { #(#field_names1),* }))152 } else {153 quote!(Ok(Self ( #(#field_names1),* )))154 };155 quote!(208 quote!(156 impl ::evm_coder::abi::AbiRead for #name {209 impl ::evm_coder::abi::AbiRead for #name {157 fn abi_read(reader: &mut ::evm_coder::abi::AbiReader) -> ::evm_coder::execution::Result<Self> {210 fn abi_read(reader: &mut ::evm_coder::abi::AbiReader) -> ::evm_coder::execution::Result<Self> {158 let is_dynamic = <Self as ::evm_coder::abi::AbiType>::is_dynamic();211 let #tuple_names = <#tuple_type as ::evm_coder::abi::AbiRead>::abi_read(reader)?;159 let size = if !is_dynamic {160 Some(<Self as ::evm_coder::abi::AbiType>::size())161 } else {162 None163 };164 let mut subresult = reader.subresult(size)?;165 #(166 let #field_names = {167 let value = <#field_types as ::evm_coder::abi::AbiRead>::abi_read(&mut subresult)?;168 if !is_dynamic {subresult.bytes_read(<#field_types as ::evm_coder::abi::AbiType>::size())};212 Ok(#struct_from_tuple)169 value170 };171 )*172173 #struct_constructor174 }213 }175 }214 }176 )215 )179fn impl_abi_write<'a>(218fn impl_abi_write<'a>(180 name: &syn::Ident,219 name: &syn::Ident,181 is_named_fields: bool,220 is_named_fields: bool,182 params_count: usize,221 tuple_type: proc_macro2::TokenStream,183 field_names: impl Iterator<Item = proc_macro2::Ident> + Clone,222 tuple_data: proc_macro2::TokenStream,184) -> proc_macro2::TokenStream {223) -> proc_macro2::TokenStream {185 let abi_write = if is_named_fields {186 quote!(187 #(188 ::evm_coder::abi::AbiWrite::abi_write(&self.#field_names, sub);189 )*190 )191 } else {192 let field_names = (0..params_count)193 .into_iter()194 .map(proc_macro2::Literal::usize_unsuffixed);195 quote!(196 #(197 ::evm_coder::abi::AbiWrite::abi_write(&self.#field_names, sub);198 )*199 )200 };201 quote!(224 quote!(202 impl ::evm_coder::abi::AbiWrite for #name {225 impl ::evm_coder::abi::AbiWrite for #name {203 fn abi_write(&self, writer: &mut ::evm_coder::abi::AbiWriter) {226 fn abi_write(&self, writer: &mut ::evm_coder::abi::AbiWriter) {204 if <Self as ::evm_coder::abi::AbiType>::is_dynamic() {227 <#tuple_type as ::evm_coder::abi::AbiWrite>::abi_write(&#tuple_data, writer)205 let mut sub = ::evm_coder::abi::AbiWriter::new();206 {207 let sub = &mut sub;208 #abi_write209 }210 writer.write_subresult(sub);211 } else {212 let sub = writer;213 #abi_write214 }215 }228 }216 }229 }217 )230 )crates/evm-coder/src/abi/impls.rsdiffbeforeafterboth88 }88 }89}89}9091impl<T: AbiWrite> AbiWrite for &T {92 fn abi_write(&self, writer: &mut AbiWriter) {93 T::abi_write(self, writer);94 }95}9697impl<T: AbiType> AbiType for &T {98 const SIGNATURE: SignatureUnit = T::SIGNATURE;99100 fn is_dynamic() -> bool {101 T::is_dynamic()102 }103104 fn size() -> usize {105 T::size()106 }107}9010891impl<T: AbiType + AbiRead + sealed::CanBePlacedInVec> AbiRead for Vec<T> {109impl<T: AbiType + AbiRead + sealed::CanBePlacedInVec> AbiRead for Vec<T> {92 fn abi_read(reader: &mut AbiReader) -> Result<Vec<T>> {110 fn abi_read(reader: &mut AbiReader) -> Result<Vec<T>> {148166149impl AbiWrite for Property {167impl AbiWrite for Property {150 fn abi_write<'a>(&'a self, writer: &mut AbiWriter) {168 fn abi_write<'a>(&'a self, writer: &mut AbiWriter) {151 (self.key.clone(), self.value.clone()).abi_write(writer);169 (&self.key, &self.value).abi_write(writer);152 }170 }153}171}154172crates/evm-coder/src/abi/traits.rsdiffbeforeafterboth44 }44 }45}45}4647impl<T: AbiWrite> AbiWrite for &T {48 fn abi_write(&self, writer: &mut AbiWriter) {49 T::abi_write(self, writer);50 }51}5246