From a06ac08560cee332254de4c8ad09538b08c1f8ee Mon Sep 17 00:00:00 2001 From: mars Date: Tue, 24 May 2022 02:28:55 -0600 Subject: [PATCH] Implement Decode derive macro --- protocol-derive/src/lib.rs | 35 +++++++++++++++++++++++++++++++++++ src/main.rs | 8 ++++++-- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/protocol-derive/src/lib.rs b/protocol-derive/src/lib.rs index cdf56c2..4f51b99 100644 --- a/protocol-derive/src/lib.rs +++ b/protocol-derive/src/lib.rs @@ -37,3 +37,38 @@ pub fn derive_encode(input: TokenStream) -> TokenStream { expanded.into() } + +#[proc_macro_derive(Decode)] +pub fn derive_decode(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + let name = input.ident; + let data = &input.data; + + let decode_members = match data { + Data::Struct(ref data) => match data.fields { + Fields::Named(ref fields) => { + let recurse = fields.named.iter().map(|f| { + let name = &f.ident; + quote_spanned! { f.span() => + #name: ::protocol::Decode::decode(reader)?, + } + }); + quote! { #(#recurse)* } + } + _ => unimplemented!(), + }, + _ => unimplemented!(), + }; + + let expanded = quote! { + impl ::protocol::Decode for #name { + fn decode(reader: &mut impl ::std::io::Read) -> ::std::io::Result { + Ok(Self { + #decode_members + }) + } + } + }; + + expanded.into() +} diff --git a/src/main.rs b/src/main.rs index fc4cc3e..ef51216 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ use protocol::*; -use protocol_derive::Encode; +use protocol_derive::{Decode, Encode}; -#[derive(Debug, Encode)] +#[derive(Debug, Decode, Encode)] struct TestData { var_int: Var, string: String, @@ -16,4 +16,8 @@ fn main() { let mut buf = Vec::new(); data.encode(&mut buf).unwrap(); println!("encoded: {:?}", buf); + + let mut reader = buf.as_slice(); + let decoded = TestData::decode(&mut reader).unwrap(); + println!("decoded: {:#?}", decoded); }