basicmethod/
lib.rs

1mod token;
2
3use proc_macro::TokenStream;
4use syn::{parse_macro_input, DeriveInput};
5use quote::quote;
6use token::{extract_unfield, set_methods_unnamed, get_methods_unnamed, enum_variants, from_trait, get_methods_mut, incdec_methods, incdec_methods_unnamed};
7use crate::token::{new_args, tup_args, set_val, set_methods, get_methods, info, root_extract, get_vis_pub, unamed_field, is_enum_field_unit};
8
9#[proc_macro_derive(BasicMethod, attributes(only,exclude))]
10pub fn basic_method_derive(input: TokenStream) -> TokenStream {
11    let dinput = parse_macro_input!(input as DeriveInput);
12    let (attrs, _vis, ident, data) = root_extract(dinput);
13    
14    let vispub = get_vis_pub();
15
16    match data {
17        syn::Data::Struct(syn::DataStruct { fields: syn::Fields::Named(fname), .. }) => {
18            let syn::FieldsNamed{ named, .. } = fname;
19            
20            let new_args = new_args(&named);
21            let tuple_args = tup_args(&named);
22            let new_setval = set_val(&named);
23
24            let set_methods = set_methods(&named, vispub.clone());
25            let get_methods = get_methods(&named, vispub.clone());
26            let get_methods_mut = get_methods_mut(&named, vispub.clone());
27            let incdec_methods = incdec_methods(&named, vispub.clone());
28            let info = info(&attrs, vispub.clone());
29        
30            return quote!{
31                impl #ident {
32                    #vispub fn new(#(#new_args),*) -> Self {
33                        Self { #(#new_setval),* }
34                    }
35                    #info
36                    #vispub fn fields() -> ::std::vec::Vec<(&'static str, &'static str)> {
37                        let mut v = vec![];
38                        #(v.push(#tuple_args));*;
39                        v
40                    }
41                    #(#set_methods)*
42                    #(#get_methods)*
43                    #(#get_methods_mut)*
44                    #(#incdec_methods)*
45                }
46            }.into()
47        }
48        syn::Data::Struct(syn::DataStruct { fields: syn::Fields::Unit, .. }) => {
49            let info = info(&attrs, vispub.clone());
50        
51            return quote!{
52                impl #ident {
53                    #info
54                }
55            }.into()
56        }
57        syn::Data::Struct(syn::DataStruct { fields: syn::Fields::Unnamed(unfield), .. }) => {
58            let punc = extract_unfield(unfield);
59            let fields = unamed_field(&punc, vispub.clone());
60            let set_methods = set_methods_unnamed(&punc, vispub.clone());
61            let get_methods = get_methods_unnamed(&punc, vispub.clone());
62            let get_methods_mut = get_methods_mut(&punc, vispub.clone());
63            let incdec_methods = incdec_methods_unnamed(&punc, vispub.clone());
64            let info = info(&attrs, vispub.clone());
65        
66            return quote!{
67                impl #ident {
68                    #info
69                    #vispub fn fields() -> ::std::vec::Vec<(&'static str)> {
70                        let mut v = vec![];
71                        #(v.push(#fields));*;
72                        v
73                    }
74                    #(#set_methods)*
75                    #(#get_methods)*
76                    #(#get_methods_mut)*
77                    #(#incdec_methods)*
78                }
79            }.into()
80        }
81        syn::Data::Enum(dataenum) => {
82            let variants = enum_variants(&dataenum.variants);
83            let from_trait = from_trait(&dataenum.variants);
84            let is_unit = is_enum_field_unit(&dataenum.variants);
85            if is_unit {
86                return quote!{
87                    impl #ident {
88                        ///Return HashSet<&'static str> that contains all enum variants as 'static str
89                        #vispub fn variants() -> ::std::collections::HashSet<&'static str> {
90                            let mut v = ::std::collections::HashSet::new();
91                            #(v.insert(#variants));*;
92                            v
93                        }
94                    }
95                    impl ::std::convert::From<&str> for #ident {
96                        fn from(value: &str) -> Self {
97                            match value {
98                                #(#from_trait),*,
99                                _ => panic!("Can not create '{}' from '{}'", stringify!(#ident), value)
100                            }
101                        }
102                    }
103                }.into();
104            } else {
105                return quote!{
106                    impl #ident {
107                        #vispub fn variants() -> ::std::vec::Vec<&'static str> {
108                            let mut v = vec![];
109                            #(v.push(#variants));*;
110                            v
111                        }
112                    }
113                }.into()
114            }
115        },
116        syn::Data::Union(_) => panic!("Union is not supported. Only struct allowed!"),
117    }
118}
119