factoryizer 1.1.0

Add factory/builder patterns automatically
Documentation
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, Data, DataStruct, DeriveInput, Field, Ident};

fn preamble(input: DeriveInput) -> (DeriveInput, Ident, DataStruct) {
    let name = input.clone().ident;
    let data = match input.clone().data {
        Data::Struct(data) => data,
        _ => panic!("Factory can only be implemented for structs"),
    };

    (input, name, data)
}

#[proc_macro_derive(Factory, attributes(skip))]
pub fn fy_derive(input: TokenStream) -> TokenStream {
    let (input, name, data) = preamble(parse_macro_input!(input as DeriveInput));
    let fields = data
        .fields
        .iter()
        .filter(|f| !f.attrs.iter().any(|a| a.path().is_ident("skip")))
        .collect::<Vec<&Field>>();

    let names = fields.iter().map(|f| f.ident.clone());
    let types = fields.iter().map(|f| f.ty.clone());

    let (i, t, w) = input.generics.split_for_impl();

    let implimentation = quote! {

        impl #i #name #t #w {

            pub fn new() -> Self {
                Self::default()
            }

            #(pub fn #names(mut self, value: impl Into<#types>) -> Self {
                self.#names = value.into();
                self
            })*
        }

    };

    TokenStream::from(implimentation)
}