zusi_protocol_derive/
lib.rs

1extern crate darling;
2extern crate proc_macro;
3
4use darling::util::SpannedValue;
5use darling::{ast, Error, FromDeriveInput, FromField};
6use syn::{parse_macro_input, DeriveInput};
7
8mod de;
9mod ser;
10
11#[derive(Debug, FromDeriveInput)]
12struct MyTraitReceiver {
13    /// The struct ident.
14    ident: syn::Ident,
15
16    /// The type's generics. You'll need these any time your trait is expected
17    /// to work with types that declare generics.
18    generics: syn::Generics,
19
20    /// Receives the body of the struct or enum. We don't care about
21    /// struct fields because we previously told darling we only accept structs.
22    data: ast::Data<(), MyFieldReceiver>,
23}
24
25#[derive(Debug, FromField)]
26#[darling(attributes(zusi))]
27struct MyFieldReceiver {
28    /// Get the ident of the field. For fields in tuple or newtype structs or
29    /// enum bodies, this can be `None`.
30    ident: Option<syn::Ident>,
31
32    /// This magic field name pulls the type from the input.
33    // ty: syn::Type,
34
35    /// We declare this as an `Option` so that during tokenization we can write
36    /// `field.volume.unwrap_or(derive_input.volume)` to facilitate field-level
37    /// overrides of struct-level settings.
38    #[darling(default)]
39    id: SpannedValue<Option<u16>>,
40}
41
42#[proc_macro_derive(Serialize, attributes(zusi))]
43pub fn serialize_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
44    let ast = parse_macro_input!(input as DeriveInput);
45    let receiver = MyTraitReceiver::from_derive_input(&ast).unwrap();
46
47    let mut errors: Vec<Error> = Vec::new();
48    let mut gen = ser::impl_serialize(&mut errors, &receiver);
49
50    if !errors.is_empty() {
51        gen.extend(Error::multiple(errors).write_errors());
52    }
53
54    gen.into()
55}
56
57#[proc_macro_derive(Deserialize, attributes(zusi))]
58pub fn deserialize_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
59    let ast = parse_macro_input!(input as DeriveInput);
60    let receiver = MyTraitReceiver::from_derive_input(&ast).unwrap();
61
62    let mut errors: Vec<Error> = Vec::new();
63    let mut gen = de::impl_deserialize(&mut errors, &receiver);
64
65    if !errors.is_empty() {
66        gen.extend(Error::multiple(errors).write_errors());
67    }
68
69    gen.into()
70}