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}