use core::panic; use proc_macro::TokenStream; use quote::{quote, quote_spanned}; use syn::{spanned::Spanned, DeriveInput}; #[proc_macro_derive(PushPopParse)] pub fn pushpop_derive_macro(item: TokenStream) -> TokenStream { let ast: DeriveInput = syn::parse(item).unwrap(); let struct_ident = ast.ident; let struct_data: syn::DataStruct = match ast.data { syn::Data::Struct(struct_data) => struct_data, syn::Data::Enum(_) => panic!("Error: Enum support not implemented"), syn::Data::Union(_) => panic!("Error: Union support not implemented"), }; let recursive = struct_data.fields.iter().map(|f| { let name = &f.ident; let ty = &f.ty; quote_spanned!(f.span()=> let #name = <#ty>::pop_ne_from(&mut source)?;) }); let names = struct_data.fields.iter().map(|f| { let name = &f.ident; quote_spanned!(f.span()=> #name) }); let pop = struct_data.fields.iter().map(|f| { let name = &f.ident; quote_spanned!(f.span()=> PopFromNE::push_ne_into(&self.#name, dest)?;) }); quote!( impl PopFromNE for #struct_ident { fn pop_ne_from(mut source: &mut &[u8]) -> anyhow::Result where Self: Sized, { #(#recursive)* Ok(#struct_ident{ #(#names),* }) } fn push_ne_into(&self, dest: &mut T) -> anyhow::Result<()> { #(#pop)* Ok(()) } }) .into() }