You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
37 lines
969 B
37 lines
969 B
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<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
|
|
#(#field_writes)*
|
|
return Ok(());
|
|
}
|
|
}
|
|
};
|
|
|
|
TokenStream::from(expanded)
|
|
}
|
|
|