getset_macro/
lib.rs

1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, Data, DeriveInput, Fields, Ident};
4
5#[proc_macro_derive(GetSet)]
6pub fn macro_learn_derive(input: TokenStream) -> TokenStream {
7    let ast = parse_macro_input!(input as DeriveInput);
8    let struct_name = &ast.ident;
9    let fields = match &ast.data {
10        Data::Struct(data) => match &data.fields {
11            Fields::Named(named_fields) => &named_fields.named,
12            _ => return quote! {}.into(),
13        },
14        _ => return quote! {}.into(),
15    };
16
17    let mut field_functions = Vec::new();
18    let mut constructor_params = Vec::new();
19    let mut constructor_args = Vec::new();
20
21    for field in fields {
22        let field_name = field.ident.as_ref().unwrap();
23        let field_type = &field.ty;
24        let get_function_name = Ident::new(&format!("get_{}", field_name), field_name.span());
25        let set_function_name = Ident::new(&format!("set_{}", field_name), field_name.span());
26
27        field_functions.push(quote! {
28            pub fn #get_function_name(&self) -> &#field_type {
29                &self.#field_name
30            }
31            pub fn #set_function_name(&mut self, set_value : #field_type) {
32                self.#field_name = set_value;
33            }
34        });
35
36        constructor_params.push(quote! {#field_name : #field_type});
37        constructor_args.push(quote! {#field_name});
38    }
39
40    let constructor_function = quote! {
41        pub fn new(#(#constructor_params),*) -> Self {
42            Self {
43                #(#constructor_args),*
44            }
45        }
46    };
47
48    quote! {
49     impl #struct_name {
50         #(#field_functions)*
51         #constructor_function
52     }
53    }
54    .into()
55}