use std::borrow::Cow;
use darling::FromDeriveInput;
use darling::ast::Data;
use itertools::Itertools;
use proc_macro2::TokenStream;
use syn::Ident;
use crate::rename::outer::OuterRenameStrategy;
use crate::target::variant::TargetVariant;
#[derive(Debug, Clone, FromDeriveInput)]
#[darling(supports(enum_unit), attributes(variants))]
pub(crate) struct TargetEnum {
ident: Ident,
data: Data<TargetVariant, ()>,
#[darling(default)]
rename: Option<OuterRenameStrategy>,
#[darling(default)]
rename_abbr: Option<OuterRenameStrategy>,
#[darling(default)]
display: bool,
#[darling(default)]
from_str: bool,
#[darling(default)]
#[cfg(feature = "serde")]
deserialize: bool,
#[darling(default)]
#[cfg(feature = "serde")]
serialize: bool,
}
impl TargetEnum {
#[inline]
pub(crate) fn ident(&self) -> &Ident {
&self.ident
}
#[inline]
pub(crate) fn variants(&self) -> &[TargetVariant] {
match self.data {
Data::Enum(ref variants) => variants,
Data::Struct(_) => unreachable!(),
}
}
#[inline]
pub(crate) fn implement_display(&self) -> bool {
self.display
}
#[inline]
pub(crate) fn implement_from_str(&self) -> bool {
self.from_str
}
#[inline]
#[cfg(feature = "serde")]
pub(crate) fn implement_deserialize(&self) -> bool {
self.deserialize
}
#[inline]
#[cfg(feature = "serde")]
pub(crate) fn implement_serialize(&self) -> bool {
self.serialize
}
#[inline]
pub(crate) fn iter_variants(&self) -> impl Iterator<Item = &TargetVariant> {
self.variants().iter()
}
#[inline]
#[rustfmt::skip]
pub(crate) fn iter_iterable_variants(&self) -> impl Iterator<Item = &TargetVariant> {
self.iter_variants().filter(|variant| variant.is_iterable())
}
pub(crate) fn variants_count(&self) -> usize {
self.iter_iterable_variants().count()
}
#[rustfmt::skip]
pub(crate) fn iter_variant_idents(&self) -> impl Iterator<Item = &Ident> {
self.iter_iterable_variants().filter_map(TargetVariant::ident)
}
#[rustfmt::skip]
pub(crate) fn iter_variant_as_str_match_branches(&self) -> impl Iterator<Item = TokenStream> {
self.iter_variants().map(|variant| variant.as_str_match_branch(self.rename))
}
#[rustfmt::skip]
pub(crate) fn iter_variant_as_str_abbr_match_branches(&self) -> impl Iterator<Item = TokenStream> {
self.iter_variants().map(|variant| variant.as_str_abbr_match_branch(self.rename, self.rename_abbr))
}
pub(crate) fn variants_list_string(&self) -> String {
Itertools::intersperse(
self.iter_iterable_variants()
.map(|variant| variant.as_quoted_string(self.rename))
.map(Cow::Owned),
Cow::Borrowed(", "),
)
.collect()
}
pub(crate) fn variants_list_string_abbr(&self) -> String {
Itertools::intersperse(
self.iter_iterable_variants()
.map(|variant| variant.as_quoted_string_abbr(self.rename, self.rename_abbr))
.map(Cow::Owned),
Cow::Borrowed(", "),
)
.collect()
}
#[rustfmt::skip]
pub(crate) fn variants_from_str_match_branches(&self) -> impl Iterator<Item = TokenStream> {
self.iter_variants().map(|variant| variant.from_str_match_branch(self.rename, self.rename_abbr))
}
#[cfg(feature = "serde")]
pub(crate) fn variants_deserialize_match_branches(&self) -> impl Iterator<Item = TokenStream> {
self.iter_variants().map(|variant| variant.deserialize_match_branch(self.rename, self.rename_abbr))
}
}