pkenum_core 0.3.1

Core logic for pkenum.
Documentation
use proc_macro2::TokenStream;
use syn::ItemEnum;
use quote::quote;
use crate::error::ParseError;
use crate::extension::FromTokens;
use crate::token::EnumToken;

/// Implmentation for a `#[derive(Display)]` which creates string values for each enum variant.
pub fn derive_display_impl(tokens: TokenStream) -> Result<TokenStream, ParseError> {
    let ast = ItemEnum::from_tokens(tokens)?;
    let model = EnumToken::from_ast(ast);

    Ok(codegen(model))
}

/// Generates variants for use in string pattern matching.
///
/// # Remarks
/// This probably shouldn't be here...
fn codegen(token: EnumToken) -> TokenStream {
    let name = token.ident;
    let cases = token.variants
        .into_iter()
        .map(|variant| {
            let ident = variant.ident;
            if variant.fields.is_none() {
                quote! { #name::#ident => stringify!(#ident), }
            } else {
                quote! { #name::#ident(..) => stringify!(#ident), }
            }
        })
        .collect::<Vec<TokenStream>>();

    quote! {
        impl #name {
            fn to_static_str(&self) -> &str {
                match self {
                    #(#cases)*
                }
            }
        }

        impl std::fmt::Display for #name {
            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
                write!(f, "{}", self.to_static_str())
            }
        }
    }
}