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}