mork_message_derive/
lib.rs

1use darling::FromDeriveInput;
2use proc_macro::{self, TokenStream};
3use quote::quote;
4use syn::{parse_macro_input, DeriveInput};
5
6#[derive(FromDeriveInput, Default)]
7#[darling(default, attributes(message))]
8struct Opts {
9    msg_code: u8,
10}
11
12#[proc_macro_derive(Message, attributes(message))]
13pub fn derive(input: TokenStream) -> TokenStream {
14    let input = parse_macro_input!(input);
15    let opts = Opts::from_derive_input(&input).expect("Wrong options");
16    let DeriveInput { ident, .. } = input;
17
18    let msg_code = opts.msg_code;
19    
20    let to_raw = quote! {
21        fn to_raw(&self) -> Vec<u8> {
22            let mut og = bincode::serialize(&self).unwrap(); 
23
24            let mut have_file = vec![#msg_code];
25            have_file.append(&mut og);
26            
27            have_file
28
29        }
30    };
31
32    let from_raw = quote! {
33        fn from_raw(slice: &[u8]) -> Result<Self, &'static str> {
34            if slice[0] != #msg_code {
35                return Err("not good msg");
36            }
37
38            let have_file: Self = match bincode::deserialize(&slice[1..]) {
39                Ok(v) => v,
40                Err(_) => return Err("deserialising failed"),
41            };
42
43            Ok(have_file)
44        }
45    };
46
47    let output = quote! {
48        impl Message for #ident {
49            #to_raw
50            #from_raw
51        }
52    };
53
54    output.into()
55}