typetrait 0.1.1

Helper macro to generate types for typestate programming
Documentation
use super::parse::Single;
use convert_case::Casing;
use proc_macro2::TokenStream;
use quote::quote;

pub fn generate(
    Single {
        attributes,
        visibility,
        trait_name,
        struct_names,
        ..
    }: Single,
) -> TokenStream {
    let private = format!(
        "__{}_private",
        trait_name.to_string().to_case(convert_case::Case::Snake)
    );
    let private = syn::Ident::new(&private, trait_name.span());
    let private_trait = syn::Ident::new(
        &format!("{}Sealed", trait_name.to_string()),
        trait_name.span(),
    );

    let types = struct_names.iter().map(|ident| {
        let ty = quote! { #visibility enum #ident {} };
        quote! {
            #(#attributes)*
            #ty

            impl #trait_name for #ident {}
        }
    });
    let private_impls = struct_names.iter().map(|ident| {
        quote! {
            impl #private_trait for super::#ident {}
        }
    });

    quote! {
        #visibility trait #trait_name: #private::#private_trait {}

        #(#types)*

        mod #private {
            pub trait #private_trait {}
            #(#private_impls)*
        }
    }
}