git.delta.rocks / unique-network / refs/commits / 038aa22b4426

difftreelog

refactor impl AbiType, AbiWrite, AbiRead via tuple

Trubnikov Sergey2022-11-28parent: #489bde0.patch.diff
in: master

3 files changed

modifiedcrates/evm-coder/procedural/src/abi_derive.rsdiffbeforeafterboth
1use proc_macro2::TokenStream;
1use quote::quote;2use quote::quote;
23
3pub(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 };
33
34 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());
3239
33 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_write
52 );
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}
68
69fn 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 });
128
129 if is_named_fields {
130 quote! {#name {#(#field_names)*}}
131 } else {
132 quote! {#name (#(#field_names)*)}
133 }
134}
57135
58fn extract_docs(attrs: &Vec<syn::Attribute>) -> syn::Result<Vec<String>> {136fn extract_docs(attrs: &Vec<syn::Attribute>) -> syn::Result<Vec<String>> {
59 attrs137 attrs
106184
107fn 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 };
117
118 params_signature.extend(quote!(shift_left(1)));
119
120 let fields_for_dynamic = field_types.clone();
121
122 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_signature
127 fixed(")")
128 );
129 fn is_dynamic() -> bool {192 fn is_dynamic() -> bool {
130 false
131 #(
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}
141201
142fn 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();
149
150 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 None
163 };
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 value
170 };
171 )*
172
173 #struct_constructor
174 }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_write
209 }
210 writer.write_subresult(sub);
211 } else {
212 let sub = writer;
213 #abi_write
214 }
215 }228 }
216 }229 }
217 )230 )
modifiedcrates/evm-coder/src/abi/impls.rsdiffbeforeafterboth
88 }88 }
89}89}
90
91impl<T: AbiWrite> AbiWrite for &T {
92 fn abi_write(&self, writer: &mut AbiWriter) {
93 T::abi_write(self, writer);
94 }
95}
96
97impl<T: AbiType> AbiType for &T {
98 const SIGNATURE: SignatureUnit = T::SIGNATURE;
99
100 fn is_dynamic() -> bool {
101 T::is_dynamic()
102 }
103
104 fn size() -> usize {
105 T::size()
106 }
107}
90108
91impl<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>> {
148166
149impl 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}
154172
modifiedcrates/evm-coder/src/abi/traits.rsdiffbeforeafterboth
44 }44 }
45}45}
46
47impl<T: AbiWrite> AbiWrite for &T {
48 fn abi_write(&self, writer: &mut AbiWriter) {
49 T::abi_write(self, writer);
50 }
51}
5246