use proc_macro2::TokenStream;
use quote::quote;
use crate::ir::{RegularVariantDefinition, TransparentVariantDefinition, VariantDefinition};
pub fn build_variant_pattern(variant: &RegularVariantDefinition) -> TokenStream {
if variant.fields.is_empty() {
quote! {}
} else {
let field_names: Vec<_> = variant.fields.iter().map(|f| &f.rust_name).collect();
quote! {
{ #(#field_names),* }
}
}
}
pub fn build_transparent_pattern(_variant: &TransparentVariantDefinition) -> TokenStream {
quote! { (inner) }
}
pub fn generate_regular_match_arms<F>(
variants: &[VariantDefinition],
body_fn: F,
) -> Vec<TokenStream>
where
F: Fn(&RegularVariantDefinition, &TokenStream) -> TokenStream,
{
variants
.iter()
.filter_map(|v| match v {
VariantDefinition::Regular(regular) => Some(regular),
VariantDefinition::Transparent(_) => None,
})
.map(|variant| {
let variant_name = &variant.name;
let pattern = build_variant_pattern(variant);
let body = body_fn(variant, &pattern);
quote! {
Self::#variant_name #pattern => { #body }
}
})
.collect()
}
pub fn generate_transparent_match_arms<F>(
variants: &[VariantDefinition],
body_fn: F,
) -> Vec<TokenStream>
where
F: Fn(&TransparentVariantDefinition, &TokenStream) -> TokenStream,
{
variants
.iter()
.filter_map(|v| match v {
VariantDefinition::Regular(_) => None,
VariantDefinition::Transparent(transparent) => Some(transparent),
})
.map(|variant| {
let variant_name = &variant.name;
let pattern = build_transparent_pattern(variant);
let body = body_fn(variant, &pattern);
quote! {
Self::#variant_name #pattern => { #body }
}
})
.collect()
}