wotw_seedgen_derive 0.1.1

Derive macro utilities used for wotw_seedgen
Documentation
use std::iter;

use proc_macro::TokenStream;
use quote::quote;

pub fn display_impl(input: syn::DeriveInput) -> TokenStream {
    let name = input.ident;

    let variants = match input.data {
        syn::Data::Enum(data_enum) => {
            data_enum.variants.into_iter().map(|variant| {
                let identifier = variant.ident;
                let mut display = identifier.to_string();

                let indices = display.match_indices(char::is_uppercase)
                    .filter_map(|(index, _)| if index > 0 { Some(index) } else { None })
                    .rev().collect::<Vec<_>>();
                for index in indices {
                    display.insert(index, ' ');
                }

                let fields = match variant.fields {
                    syn::Fields::Named(_) => return quote! { #name::#identifier { .. } => #display },
                    syn::Fields::Unnamed(fields) => fields.unnamed,
                    syn::Fields::Unit => return quote! { #name::#identifier => #display },
                };
                let eat_fields = iter::repeat("_")
                    .take(fields.len())
                    .collect::<Vec<_>>();
                quote! {
                    #name::#identifier(#(#eat_fields),*) => #display
                }
            }).collect::<Vec<_>>()
        },
        _ => panic!("Expected enum"),
    };

    quote! {
        impl std::fmt::Display for #name {
            fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
                let display = match self {
                    #(#variants),*
                };
                write!(f, "{}", display)
            }
        }
    }.into()
}