mork_message_derive/
lib.rs1use 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}