stwo_cairo_serialize_derive/
lib.rs1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, Data, DeriveInput, Fields};
4
5#[proc_macro_derive(CairoSerialize)]
6pub fn derive_cairo_serialize(input: TokenStream) -> TokenStream {
7 let input = parse_macro_input!(input as DeriveInput);
9
10 let struct_name = input.ident;
11 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
12
13 let fields = match input.data {
15 Data::Struct(ref data_struct) => match &data_struct.fields {
16 Fields::Named(ref fields_named) => &fields_named.named,
17 Fields::Unnamed(_) | Fields::Unit => {
18 return syn::Error::new_spanned(
19 struct_name,
20 "CairoSerialize can only be derived for structs with named fields.",
21 )
22 .to_compile_error()
23 .into();
24 }
25 },
26 _ => {
27 return syn::Error::new_spanned(
28 struct_name,
29 "CairoSerialize can only be derived for structs.",
30 )
31 .to_compile_error()
32 .into();
33 }
34 };
35
36 let serialize_body = fields.iter().map(|f| {
38 let field_name = &f.ident;
39 quote! {
40 CairoSerialize::serialize(&self.#field_name, output);
41 }
42 });
43
44 let expanded = quote! {
46 impl #impl_generics ::stwo_cairo_serialize::CairoSerialize for #struct_name #ty_generics #where_clause {
47 fn serialize(&self, output: &mut Vec<::starknet_ff::FieldElement>) {
48 #(#serialize_body)*
49 }
50 }
51 };
52
53 TokenStream::from(expanded)
54}
55
56#[proc_macro_derive(CairoDeserialize)]
57pub fn derive_cairo_deserialize(input: TokenStream) -> TokenStream {
58 let input = parse_macro_input!(input as DeriveInput);
60
61 let struct_name = input.ident;
62 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
63
64 let fields = match input.data {
66 Data::Struct(ref data_struct) => match &data_struct.fields {
67 Fields::Named(ref fields_named) => &fields_named.named,
68 Fields::Unnamed(_) | Fields::Unit => {
69 return syn::Error::new_spanned(
70 struct_name,
71 "CairoDeserialize can only be derived for structs with named fields.",
72 )
73 .to_compile_error()
74 .into();
75 }
76 },
77 _ => {
78 return syn::Error::new_spanned(
79 struct_name,
80 "CairoDeserialize can only be derived for structs.",
81 )
82 .to_compile_error()
83 .into();
84 }
85 };
86
87 let deserialize_body = fields.iter().map(|f| {
89 let field_name = &f.ident;
90 quote! {
91 #field_name: ::stwo_cairo_serialize::CairoDeserialize::deserialize(data),
92 }
93 });
94
95 let expanded = quote! {
97 impl #impl_generics ::stwo_cairo_serialize::CairoDeserialize for #struct_name #ty_generics #where_clause {
98 fn deserialize<'a>(
99 data: &mut impl Iterator<Item = &'a ::starknet_ff::FieldElement>,
100 ) -> Self {
101 Self{ #(#deserialize_body)* }
102 }
103 }
104 };
105
106 TokenStream::from(expanded)
107}