basicmethod 0.1.2

Add constructor, get and set method using derive macro
Documentation
mod token;

use proc_macro::TokenStream;
use syn::{parse_macro_input, DeriveInput};
use quote::quote;
use token::{extract_unfield, set_methods_unnamed, get_methods_unnamed, enum_variants, from_trait, get_methods_mut, incdec_methods, incdec_methods_unnamed};
use crate::token::{new_args, tup_args, set_val, set_methods, get_methods, info, root_extract, get_vis_pub, unamed_field, is_enum_field_unit};

#[proc_macro_derive(BasicMethod, attributes(only,exclude))]
pub fn basic_method_derive(input: TokenStream) -> TokenStream {
    let dinput = parse_macro_input!(input as DeriveInput);
    let (attrs, _vis, ident, data) = root_extract(dinput);
    
    let vispub = get_vis_pub();

    match data {
        syn::Data::Struct(syn::DataStruct { fields: syn::Fields::Named(fname), .. }) => {
            let syn::FieldsNamed{ named, .. } = fname;
            
            let new_args = new_args(&named);
            let tuple_args = tup_args(&named);
            let new_setval = set_val(&named);

            let set_methods = set_methods(&named, vispub.clone());
            let get_methods = get_methods(&named, vispub.clone());
            let get_methods_mut = get_methods_mut(&named, vispub.clone());
            let incdec_methods = incdec_methods(&named, vispub.clone());
            let info = info(&attrs, vispub.clone());
        
            return quote!{
                impl #ident {
                    #vispub fn new(#(#new_args),*) -> Self {
                        Self { #(#new_setval),* }
                    }
                    #info
                    #vispub fn fields() -> ::std::vec::Vec<(&'static str, &'static str)> {
                        let mut v = vec![];
                        #(v.push(#tuple_args));*;
                        v
                    }
                    #(#set_methods)*
                    #(#get_methods)*
                    #(#get_methods_mut)*
                    #(#incdec_methods)*
                }
            }.into()
        }
        syn::Data::Struct(syn::DataStruct { fields: syn::Fields::Unit, .. }) => {
            let info = info(&attrs, vispub.clone());
        
            return quote!{
                impl #ident {
                    #info
                }
            }.into()
        }
        syn::Data::Struct(syn::DataStruct { fields: syn::Fields::Unnamed(unfield), .. }) => {
            let punc = extract_unfield(unfield);
            let fields = unamed_field(&punc, vispub.clone());
            let set_methods = set_methods_unnamed(&punc, vispub.clone());
            let get_methods = get_methods_unnamed(&punc, vispub.clone());
            let get_methods_mut = get_methods_mut(&punc, vispub.clone());
            let incdec_methods = incdec_methods_unnamed(&punc, vispub.clone());
            let info = info(&attrs, vispub.clone());
        
            return quote!{
                impl #ident {
                    #info
                    #vispub fn fields() -> ::std::vec::Vec<(&'static str)> {
                        let mut v = vec![];
                        #(v.push(#fields));*;
                        v
                    }
                    #(#set_methods)*
                    #(#get_methods)*
                    #(#get_methods_mut)*
                    #(#incdec_methods)*
                }
            }.into()
        }
        syn::Data::Enum(dataenum) => {
            let variants = enum_variants(&dataenum.variants);
            let from_trait = from_trait(&dataenum.variants);
            let is_unit = is_enum_field_unit(&dataenum.variants);
            if is_unit {
                return quote!{
                    impl #ident {
                        ///Return HashSet<&'static str> that contains all enum variants as 'static str
                        #vispub fn variants() -> ::std::collections::HashSet<&'static str> {
                            let mut v = ::std::collections::HashSet::new();
                            #(v.insert(#variants));*;
                            v
                        }
                    }
                    impl ::std::convert::From<&str> for #ident {
                        fn from(value: &str) -> Self {
                            match value {
                                #(#from_trait),*,
                                _ => panic!("Can not create '{}' from '{}'", stringify!(#ident), value)
                            }
                        }
                    }
                }.into();
            } else {
                return quote!{
                    impl #ident {
                        #vispub fn variants() -> ::std::vec::Vec<&'static str> {
                            let mut v = vec![];
                            #(v.push(#variants));*;
                            v
                        }
                    }
                }.into()
            }
        },
        syn::Data::Union(_) => panic!("Union is not supported. Only struct allowed!"),
    }
}