use proc_macro2::Ident;
use syn::spanned::Spanned;
use syn::{Fields, ItemEnum, Type, Variant};
use crate::error::InvalidInput;
pub(crate) struct SingleFieldEnum {
variants: Vec<SingleFieldVariant>,
}
impl SingleFieldEnum {
pub fn first_variant(&self) -> &SingleFieldVariant {
&self.variants[0]
}
pub fn variants(&self) -> &[SingleFieldVariant] {
&self.variants
}
}
pub(crate) struct SingleFieldVariant {
pub name: Ident,
pub type_: Type,
}
pub(crate) fn parse_enum_variants(enum_: &ItemEnum) -> Result<SingleFieldEnum, InvalidInput> {
let variants: Result<Vec<_>, _> = enum_
.variants
.iter()
.map(|variant| {
Ok(SingleFieldVariant {
name: variant.ident.clone(),
type_: get_variant_only_field_type(variant)?.clone(),
})
})
.collect();
let variants = variants?;
if variants.is_empty() {
return Err(InvalidInput::NoVariants(enum_.span()));
}
Ok(SingleFieldEnum { variants })
}
fn get_variant_only_field_type(variant: &Variant) -> Result<&Type, InvalidInput> {
match &variant.fields {
Fields::Unnamed(f) if f.unnamed.len() == 1 => Ok(&f.unnamed[0].ty),
_ => Err(InvalidInput::InvalidVariant(variant.span())),
}
}