netherite_derive/
lib.rs

1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, parse_quote, Data, DeriveInput};
4
5#[proc_macro_derive(Serialize)]
6pub fn serialize(tree: TokenStream) -> TokenStream {
7    let mut serialize_struct = parse_macro_input!(tree as DeriveInput);
8    let Data::Struct(data) = serialize_struct.data else { panic!("expected struct") };
9
10    let serialize = data.fields.iter().map(|field| field.ident.as_ref());
11    let size = serialize.clone();
12
13    for type_param in serialize_struct.generics.type_params_mut() {
14        type_param.bounds.push(parse_quote!(Serialize))
15    }
16
17    let ident = serialize_struct.ident;
18    let (impl_generics, ty_generics, where_generics) = serialize_struct.generics.split_for_impl();
19
20    quote!(
21        impl #impl_generics netherite::Serialize for #ident #ty_generics #where_generics {
22            fn serialize(&self, mut buf: impl netherite::_bytes_export::BufMut) {
23                #(self.#serialize.serialize(&mut buf);)*
24            }
25
26            fn size(&self) -> usize {
27                0 #( + self.#size.size())*
28            }
29        }
30    )
31    .into()
32}
33
34#[proc_macro_derive(Deserialize)]
35pub fn deserialize(tree: TokenStream) -> TokenStream {
36    let mut input = parse_macro_input!(tree as DeriveInput);
37    let Data::Struct(data) = input.data else { panic!("expected struct") };
38
39    for tp in input.generics.type_params_mut() {
40        tp.bounds.push(parse_quote!(Deserialize))
41    }
42
43    let ident = input.ident;
44    let (impl_generics, struct_generics, where_clause) = input.generics.split_for_impl();
45    let fields = data.fields.iter().map(|field| field.ident.as_ref());
46
47    quote!(
48        impl #impl_generics netherite::Deserialize for #ident #struct_generics #where_clause {
49            fn deserialize(mut buffer: impl netherite::_bytes_export::Buf)
50            -> std::result::Result<Self, netherite::DeError> {
51                Ok(Self {
52                    #(#fields: Deserialize::deserialize(&mut buffer)?),*
53                })
54            }
55        }
56    )
57    .into()
58}