1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, Data, DeriveInput, Fields};
4
5#[proc_macro_derive(JaguarSerialize)]
6pub fn derive_serialize(input: TokenStream) -> TokenStream {
7 let input = parse_macro_input!(input as DeriveInput);
8 let name = input.ident;
9 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
10
11 let fields = match input.data {
12 Data::Struct(data) => match data.fields {
13 Fields::Named(fields) => fields.named,
14 Fields::Unnamed(fields) => fields.unnamed,
15 Fields::Unit => return quote! {}.into(),
16 },
17 _ => return quote! {}.into(),
18 };
19
20 let field_serialize = fields.iter().map(|field| {
21 let field_name = field.ident.as_ref().unwrap();
22 quote! {
23 self.#field_name.serialize(ser)?;
24 }
25 });
26
27 let expanded = quote! {
28 impl #impl_generics jaguar::JaguarSerialize for #name #ty_generics #where_clause {
29 fn serialize(&self, ser: &mut jaguar::JaguarSerializer) -> Result<(), jaguar::SerError> {
30 #(#field_serialize)*
31 Ok(())
32 }
33 }
34 };
35
36 expanded.into()
37}
38
39#[proc_macro_derive(JaguarDeserialize)]
40pub fn derive_deserialize(input: TokenStream) -> TokenStream {
41 let input = parse_macro_input!(input as DeriveInput);
42 let name = input.ident;
43 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
44
45 let fields = match input.data {
46 Data::Struct(data) => match data.fields {
47 Fields::Named(fields) => fields.named,
48 Fields::Unnamed(fields) => fields.unnamed,
49 Fields::Unit => return quote! {}.into(),
50 },
51 _ => return quote! {}.into(),
52 };
53
54 let field_deserialize = fields.iter().map(|field| {
55 let field_name = field.ident.as_ref().unwrap();
56 let field_type = &field.ty;
57 quote! {
58 let #field_name = <#field_type as jaguar::JaguarDeserialize>::deserialize(de)?;
59 }
60 });
61
62 let field_names = fields.iter().map(|field| {
63 field.ident.as_ref().unwrap()
64 });
65
66 let expanded = quote! {
67 impl<'a> #impl_generics jaguar::JaguarDeserialize<'a> for #name #ty_generics #where_clause {
68 fn deserialize(de: &mut jaguar::JaguarDeserializer<'a>) -> Result<Self, jaguar::SerError> {
69 #(#field_deserialize)*
70 Ok(Self {
71 #(#field_names,)*
72 })
73 }
74 }
75 };
76
77 expanded.into()
78}