new_derivable 0.2.0

Create new implementations with just a paste of a macro
Documentation
use proc_macro::TokenStream;
use proc_macro2::Span;
use quote::quote;
use syn::{parse_macro_input, Data, DeriveInput, Error, Fields, Ident, Type};

enum StructType {
    Named,
    Unnamed,
}

#[proc_macro_derive(New)]
pub fn new_macro(_input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(_input as DeriveInput);
    let name = &input.ident;
    let struct_data = match &input.data {
        Data::Struct(data) => {
            match &data.fields {
                Fields::Named(named) => {
                    let mut struct_fields: (StructType, Vec<(Ident, &Type)>) =
                        (StructType::Named, Vec::new());
                    let mut iter = named.named.iter();

                    while let Some(field) = iter.next() {
                        // This will always have a name, well should? We don't
                        // allow unamed structs.
                        let field_name = field.ident.clone().unwrap();

                        struct_fields.1.push((field_name, &field.ty))
                    }
                    struct_fields
                }
                Fields::Unnamed(unnamed) => {
                    let mut struct_fields: (StructType, Vec<(Ident, &Type)>) =
                        (StructType::Unnamed, Vec::new());
                    let mut iter = unnamed.unnamed.iter().enumerate();

                    while let Some((i, field)) = iter.next() {
                        struct_fields.1.push((
                            Ident::new(&format!("_{}", &i), Span::call_site()).clone(),
                            &field.ty,
                        ));
                    }
                    struct_fields
                }
                _ => {
                    return TokenStream::from(
                        Error::new_spanned(
                            input,
                            "This macro only supports Tuple and Braced Structs.",
                        )
                        .to_compile_error(),
                    );
                }
            }
        }
        _ => {
            return TokenStream::from(
                Error::new_spanned(input, "This macro can only be used on Structs.")
                    .to_compile_error(),
            );
        }
    };

    let mut arguements = Vec::new();
    let mut names = Vec::new();

    for field in struct_data.1 {
        let name = field.0;
        let ptype = field.1;
        arguements.push(quote! { #name: #ptype });
        names.push(name)
    }

    let expr = match struct_data.0 {
        StructType::Named => {
            quote! {
                Self {
                    #(#names),*
                }
            }
        }
        StructType::Unnamed => {
            quote! {
                Self (
                    #(#names),*
                )
            }
        }
    };

    let expanded = quote! {
        impl #name {
            fn new(#(#arguements),*) -> Self {
                #expr
            }
        }
    };

    TokenStream::from(expanded)
}