z80_forth_derive 0.1.1

Derive macros for the z80_forth compiler
Documentation
use proc_macro::TokenStream;
use quote;
use syn;

const BAD_FIELDS_ERR: &'static str = "Fields of type must all have names to implement StringFields";
fn unwrap_fields(fields: syn::Fields)
    -> syn::punctuated::Punctuated<syn::Field, syn::token::Comma> {
    match fields {
        syn::Fields::Named(fil) => fil.named,
        syn::Fields::Unit => syn::punctuated::Punctuated::new(),
        _ => panic!("Tuples cannot implement StringFields"),
    }
}


#[proc_macro_derive(StringFields)]
pub fn named_enum_macro(input: TokenStream) -> TokenStream {
    let ast = syn::parse_macro_input!(input as syn::DeriveInput);
    let name = &ast.ident;
    let type_fields: Vec<syn::Ident> = match ast.data {
        syn::Data::Struct(dat)  => unwrap_fields(dat.fields)
                                    .iter()
                                    .map(|val|
                                        val.ident.clone().expect(BAD_FIELDS_ERR)
                                    )
                                    .collect(),
        syn::Data::Union(dat)   => dat
                                    .fields
                                    .named
                                    .iter()
                                    .map(|val| 
                                        val.ident.clone().expect(BAD_FIELDS_ERR)
                                    )
                                    .collect(),
        syn::Data::Enum(dat)    => dat
                                    .variants
                                    .iter()
                                    .map(|val| val.ident.clone())
                                    .collect(),
    };
    let type_fields_iter = type_fields.iter();
    quote::quote!{
        impl z80_forth_derive_internals::StringFields for #name {
            fn fields() -> &'static[&'static str] {
                return &[#(stringify!(#type_fields_iter)),*];
            }
        }
    }.into()
}