nitinol_macro/
lib.rs

1use proc_macro::TokenStream;
2use darling::FromDeriveInput;
3use quote::quote;
4
5#[proc_macro_derive(Command)]
6pub fn derive_command(input: TokenStream) -> TokenStream {
7    let input = syn::parse_macro_input!(input as syn::DeriveInput);
8    let input_name = &input.ident;
9    
10    let token = quote! {
11        impl ::nitinol::Command for #input_name {}
12    };
13    
14    token.into()
15}
16
17#[derive(FromDeriveInput)]
18#[darling(attributes(persist))]
19struct PersistAttribute {
20    #[darling(default)]
21    key: String,
22    enc: String,
23    dec: String
24}
25
26#[proc_macro_derive(Event, attributes(persist))]
27pub fn derive_event(input: TokenStream) -> TokenStream {
28    let input = syn::parse_macro_input!(input as syn::DeriveInput);
29    let attr = match PersistAttribute::from_derive_input(&input) {
30        Ok(v) => v,
31        Err(e) => return e.write_errors().into()
32    };
33    let input_name = &input.ident;
34    
35    let event_type = if attr.key.is_empty() {
36        to_kebab_case(&input_name.to_string())
37    } else {
38        attr.key
39    };
40    
41    let enc = syn::parse_str::<syn::Expr>(&attr.enc).unwrap();
42    let dec = syn::parse_str::<syn::Expr>(&attr.dec).unwrap();
43    
44    let token = quote! {
45        impl ::nitinol::Event for #input_name {
46            const EVENT_TYPE: &'static str = #event_type;
47            fn as_bytes(&self) -> Result<Vec<u8>, ::nitinol::errors::SerializeError> {
48                Ok(#enc(self)?)
49            }
50            fn from_bytes(bytes: &[u8]) -> Result<Self, ::nitinol::errors::DeserializeError> {
51                Ok(#dec(bytes)?)
52            }
53        }
54    };
55    
56    token.into()
57}
58
59fn to_kebab_case(input: &str) -> String {
60    input.chars().fold(String::new(), |mut acc, c| {
61        if c.is_uppercase() {
62            if !acc.is_empty() {
63                acc.push('-');
64            }
65            acc.push(c.to_ascii_lowercase());
66        } else {
67            acc.push(c);
68        }
69        acc
70    })
71}