Skip to content

Commit 2285e39

Browse files
MrWad3rRexagon
authored andcommitted
feat: Add proper custom WithAbiType macro derivation
1 parent 7e5a9f0 commit 2285e39

File tree

2 files changed

+40
-26
lines changed

2 files changed

+40
-26
lines changed

abi-proc/src/derive_from_abi.rs

+38-24
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
use crate::common;
2+
use crate::common::FieldAttributes;
13
use quote::quote;
2-
use syn::{Fields, FieldsNamed};
34

45
pub fn impl_derive(input: syn::DeriveInput) -> Result<proc_macro2::TokenStream, syn::Error> {
56
let data = match &input.data {
@@ -18,38 +19,51 @@ pub fn impl_derive(input: syn::DeriveInput) -> Result<proc_macro2::TokenStream,
1819
}
1920
};
2021

22+
let mut struct_fields = Vec::new();
23+
2124
let ident = &input.ident;
2225

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+
}
4435

4536
let token_stream = quote! {
4637
impl ::everscale_types::abi::FromAbi for #ident {
4738
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),* })
5044
}
5145
}
5246
};
5347

5448
Ok(token_stream)
5549
}
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+
}

abi-proc/src/derive_with_abi_type.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub fn impl_derive(input: syn::DeriveInput) -> Result<proc_macro2::TokenStream,
3939
};
4040

4141
let token_stream = quote! {
42-
impl WithAbiType for #ident {
42+
impl ::everscale_types::abi::WithAbiType for #ident {
4343
fn abi_type() -> ::everscale_types::abi::AbiType {
4444
::everscale_types::abi::AbiType::tuple(#abi_values_slice)
4545
}
@@ -61,7 +61,7 @@ pub fn construct_with_abi_type(
6161
let custom_name = to_change.to_string();
6262

6363
match &attrs.custom_handler {
64-
Some(handler) => quote!(#handler::abi_type(self.#field_name).named(#custom_name)),
64+
Some(handler) => quote!(#handler::abi_type().named(#custom_name)),
6565
None => quote!(<#ty>::abi_type().named(#custom_name)),
6666
}
6767
}

0 commit comments

Comments
 (0)