1
+ use crate :: common;
2
+ use crate :: common:: FieldAttributes ;
1
3
use quote:: quote;
2
- use syn:: { Fields , FieldsNamed } ;
3
4
4
5
pub fn impl_derive ( input : syn:: DeriveInput ) -> Result < proc_macro2:: TokenStream , syn:: Error > {
5
6
let data = match & input. data {
@@ -18,38 +19,51 @@ pub fn impl_derive(input: syn::DeriveInput) -> Result<proc_macro2::TokenStream,
18
19
}
19
20
} ;
20
21
22
+ let mut struct_fields = Vec :: new ( ) ;
23
+
21
24
let ident = & input. ident ;
22
25
23
- let fields = match & data. fields {
24
- Fields :: Named ( FieldsNamed { named, .. } ) => {
25
- let mut fields = Vec :: new ( ) ;
26
- for i in named {
27
- let Some ( name) = & i. ident else {
28
- return Err ( syn:: Error :: new_spanned (
29
- & input,
30
- "FromAbi does not support unnamed fields " ,
31
- ) ) ;
32
- } ;
33
- fields. push ( quote ! ( #name) ) ;
34
- }
35
- fields
36
- }
37
- _ => {
38
- return Err ( syn:: Error :: new_spanned (
39
- & input,
40
- "FromAbi does not support unnamed fields " ,
41
- ) )
42
- }
43
- } ;
26
+ for i in & data. fields {
27
+ let Some ( name) = & i. ident else {
28
+ continue ;
29
+ } ;
30
+
31
+ let attributes = common:: extract_field_attributes ( i. attrs . as_slice ( ) ) ;
32
+ let token = construct_from_abi ( name, & attributes) ;
33
+ struct_fields. push ( token) ;
34
+ }
44
35
45
36
let token_stream = quote ! {
46
37
impl :: everscale_types:: abi:: FromAbi for #ident {
47
38
fn from_abi( value: :: everscale_types:: abi:: AbiValue ) -> anyhow:: Result <Self > {
48
- let ( #( #fields) , * ) = <_>:: from_abi( value) ?;
49
- Ok ( Self { #( #fields) , * } )
39
+ let :: everscale_types:: abi:: AbiValue :: Tuple ( inner) = value else {
40
+ anyhow:: bail!( "AbiValue has incorrect type" )
41
+ } ;
42
+ let mut iter = inner. iter( ) ;
43
+ Ok ( Self { #( #struct_fields) , * } )
50
44
}
51
45
}
52
46
} ;
53
47
54
48
Ok ( token_stream)
55
49
}
50
+
51
+ pub fn construct_from_abi (
52
+ field_name : & syn:: Ident ,
53
+ attrs : & FieldAttributes ,
54
+ ) -> proc_macro2:: TokenStream {
55
+ match & attrs. custom_handler {
56
+ Some ( handler) => {
57
+ quote ! ( #field_name: #handler:: from_abi(
58
+ iter. next( )
59
+ . ok_or( anyhow:: anyhow!( "unable to get field from abi" ) ) ?. value. clone( ) ) ?
60
+ )
61
+ }
62
+ None => {
63
+ quote ! ( #field_name: <_>:: from_abi(
64
+ iter. next( )
65
+ . ok_or( anyhow:: anyhow!( "unable to get field from abi" ) ) ?. value. clone( ) ) ?
66
+ )
67
+ }
68
+ }
69
+ }
0 commit comments