derive_struct_fields_macro/
lib.rs1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, DeriveInput};
4
5#[proc_macro_derive(StructFields)]
6pub fn derive_struct_fields(input: TokenStream) -> TokenStream {
7 let input = parse_macro_input!(input as DeriveInput);
8 let name = &input.ident;
9 let fields = match input.data {
10 syn::Data::Struct(data) => data.fields,
11 _ => panic!("StructFields can only be derived for structs"),
12 };
13
14 let field_infos: Vec<_> = fields
15 .iter()
16 .map(|f| {
17 let field_name = &f.ident;
18 let field_type = &f.ty;
19 quote! {
20 derive_struct_fields::StructFieldInfo {
21 name: stringify!(#field_name),
22 field_type: stringify!(#field_type),
23 }
24 }
25 })
26 .collect();
27
28 let field_names: Vec<_> = fields
29 .iter()
30 .map(|f| {
31 let field_name = &f.ident;
32 quote! {
33 stringify!(#field_name).to_string()
34 }
35 })
36 .collect();
37
38 let expanded = quote! {
39 impl derive_struct_fields::StructFields for #name {
40 fn struct_fields() -> Vec<derive_struct_fields::StructFieldInfo> {
41 vec![ #(#field_infos),* ]
42 }
43 fn struct_field_names() -> Vec<String> {
44 vec![ #(#field_names),* ]
45 }
46
47 }
48 };
49
50 TokenStream::from(expanded)
51}