bytestruct_derive/
lib.rs

1extern crate proc_macro;
2
3use quote::quote;
4use proc_macro::TokenStream;
5use syn::{parse_macro_input, Data, DeriveInput};
6
7#[proc_macro_derive(ByteStruct, attributes(default, escape))]
8pub fn derive_byte_struct(input: TokenStream) -> TokenStream {
9    let input = parse_macro_input!(input as DeriveInput);
10
11    let name = input.ident;
12
13    if let Data::Struct(data) = &input.data {
14        let fields = data.fields.iter().map(|field| {
15            let name = field.ident.as_ref().unwrap();
16            let ty = &field.ty;
17
18            quote! {
19                #name: <#ty as ::bytestruct::ReadFrom<T>>::read_from(source)?
20            }
21        });
22
23        let gen = quote! {
24            impl<T: ::std::io::Read> ::bytestruct::ReadFrom<T> for #name {
25                fn read_from(source: &mut T) -> ::std::io::Result<Self> where Self: Sized {
26                    Ok(Self {
27                        #(#fields),*
28                    })
29                }
30            }
31        };
32
33        return gen.into();
34    } else {
35        panic!("Only structs are supported")
36    }
37}