extern crate proc_macro; use proc_macro::TokenStream; use quote::quote; use syn::{parse_macro_input, DeriveInput}; #[proc_macro_derive(BinarySerializable)] pub fn derive_binary_serializable(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); let name = input.ident; let fields = match input.data { syn::Data::Struct(s) => s.fields, _ => panic!("#[derive(BinarySerializable)] only works on structs"), }; let field_writes = fields.iter().map(|f| { let ident = f.ident.as_ref().unwrap(); quote! { BinarySerializable::write_to(&self.#ident, writer)?; } }); let expanded = quote! { impl BinarySerializable for #name { fn write_to(&self, writer: &mut W) -> std::io::Result<()> { #(#field_writes)* return Ok(()); } } }; TokenStream::from(expanded) }