1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, ItemStruct, Fields};
4
5#[proc_macro_attribute]
6pub fn model(_attr: TokenStream, item: TokenStream) -> TokenStream {
7 let input = parse_macro_input!(item as ItemStruct);
8 let name = &input.ident;
9 let vis = &input.vis;
10 let attrs = &input.attrs;
11
12 let fields = match &input.fields {
13 Fields::Named(named) => &named.named,
14 _ => {
15 return syn::Error::new_spanned(&input, "Expected a struct with named fields")
16 .to_compile_error()
17 .into()
18 }
19 };
20
21 let original_fields = fields.iter();
22
23 let expanded = quote! {
24 #(#attrs)*
25 #vis struct #name {
26 #(#original_fields,)*
27
28 pub attrs: std::collections::HashMap<String, crate::model::LibValue>,
29 pub groups: Vec<crate::model::LibGroup>,
30 }
31
32 impl crate::model::Model for #name {
33 fn attrs(&self) -> &std::collections::HashMap<String, crate::model::LibValue> {
34 &self.attrs
35 }
36
37 fn groups(&self) -> &[crate::model::LibGroup] {
38 &self.groups
39 }
40 }
41 };
42
43 TokenStream::from(expanded)
44}