finestre_init_with_size_derive/
lib.rs1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, DeriveInput, Data, Fields};
4
5#[proc_macro_derive(InitWithSize, attributes(size_field))]
6pub fn derive_init_with_size(input: TokenStream) -> TokenStream {
7 let input = parse_macro_input!(input as DeriveInput);
8 let struct_name = input.ident;
9
10 let mut size_field_name = quote! { size };
12
13 if let Data::Struct(data_struct) = input.data {
14 if let Fields::Named(fields_named) = data_struct.fields {
15 for field in fields_named.named {
16 for attr in &field.attrs {
17 if attr.path().is_ident("size_field") {
18 if let Some(ident) = field.ident.as_ref() {
19 size_field_name = quote! { #ident };
20 }
21 }
22 }
23 }
24 }
25 }
26
27 let expanded = quote! {
28 impl #struct_name {
29 pub fn init() -> Self {
30 let mut s: Self = unsafe { std::mem::zeroed() };
31 s.#size_field_name = std::mem::size_of::<Self>() as _;
32 s
33 }
34 }
35 };
36
37 TokenStream::from(expanded)
38}