playready_macros/
lib.rs

1use proc_macro::{self, TokenStream};
2use quote::quote;
3use syn::{DeriveInput, parse_macro_input};
4
5#[proc_macro_derive(StructTag, attributes(struct_tag))]
6pub fn derive_struct_tag(input: TokenStream) -> TokenStream {
7    let input: DeriveInput = parse_macro_input!(input);
8    let ident = &input.ident;
9
10    let tag: syn::LitInt = input
11        .attrs
12        .into_iter()
13        .find(|attr| attr.path().is_ident("struct_tag"))
14        .expect("struct_tag not found")
15        .parse_args()
16        .expect("Failed to parse struct_tag argument");
17
18    let output = quote! {
19        impl StructTag for #ident {
20            const TAG: u16 = #tag;
21        }
22    };
23
24    output.into()
25}
26
27#[proc_macro_derive(StructRawSize)]
28pub fn derive_size(input: TokenStream) -> TokenStream {
29    let input: DeriveInput = parse_macro_input!(input);
30    let ident = &input.ident;
31
32    let data = match input.data {
33        syn::Data::Struct(data_struct) => data_struct,
34        _ => unimplemented!(),
35    };
36
37    let fields = data.fields.iter().map(|field| {
38        let ident = &field.ident;
39        quote! { self.#ident.get_raw_size() }
40    });
41
42    quote! {
43        impl StructRawSize for #ident {
44            #[inline]
45            fn get_raw_size(&self) -> usize {
46                0 #(+ #fields)*
47            }
48        }
49    }
50    .into()
51}