Skip to content

Commit

Permalink
add support for unlabeled and unindexed enum variants
Browse files Browse the repository at this point in the history
  • Loading branch information
KodrAus committed Mar 26, 2024
1 parent 0b775c8 commit 072cff7
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 3 deletions.
50 changes: 50 additions & 0 deletions derive_macros/src/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,56 @@ impl RawAttribute for UnindexedFieldsAttr {
}
}

/**
The `unlabeled_variants` attribute.
This attribute signals that all variants should be unlabeled.
*/
pub(crate) struct UnlabeledVariantsAttr;

impl SvalAttribute for UnlabeledVariantsAttr {
type Result = bool;

fn from_lit(&self, lit: &Lit) -> Self::Result {
if let Lit::Bool(ref b) = lit {
b.value
} else {
panic!("unexpected value")
}
}
}

impl RawAttribute for UnlabeledVariantsAttr {
fn key(&self) -> &str {
"unlabeled_variants"
}
}

/**
The `unindexed_variants` attribute.
This attribute signals that all variants should be unindexed.
*/
pub(crate) struct UnindexedVariantsAttr;

impl SvalAttribute for UnindexedVariantsAttr {
type Result = bool;

fn from_lit(&self, lit: &Lit) -> Self::Result {
if let Lit::Bool(ref b) = lit {
b.value
} else {
panic!("unexpected value")
}
}
}

impl RawAttribute for UnindexedVariantsAttr {
fn key(&self) -> &str {
"unindexed_variants"
}
}

/**
The `dynamic` attribute.
Expand Down
22 changes: 19 additions & 3 deletions derive_macros/src/derive/derive_enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ pub(crate) struct EnumAttrs {
tag: Option<Path>,
label: Option<LabelValue>,
index: Option<IndexValue>,
unlabeled_variants: bool,
unindexed_variants: bool,
dynamic: bool,
}

Expand All @@ -29,13 +31,17 @@ impl EnumAttrs {
&attr::LabelAttr,
&attr::IndexAttr,
&attr::DynamicAttr,
&attr::UnlabeledVariantsAttr,
&attr::UnindexedVariantsAttr,
],
attrs,
);

let tag = attr::get_unchecked("enum", attr::TagAttr, attrs);
let label = attr::get_unchecked("enum", attr::LabelAttr, attrs);
let index = attr::get_unchecked("enum", attr::IndexAttr, attrs);
let unlabeled_variants = attr::get_unchecked("enum", attr::UnlabeledVariantsAttr, attrs).unwrap_or(false);
let unindexed_variants = attr::get_unchecked("enum", attr::UnindexedVariantsAttr, attrs).unwrap_or(false);
let dynamic = attr::get_unchecked("enum", attr::DynamicAttr, attrs).unwrap_or(false);

if dynamic {
Expand All @@ -48,6 +54,8 @@ impl EnumAttrs {
tag,
label,
index,
unlabeled_variants,
unindexed_variants,
dynamic,
}
}
Expand Down Expand Up @@ -81,7 +89,7 @@ pub(crate) fn derive_enum<'a>(

let mut variant_index = |index: Option<Index>, discriminant: Option<IndexValue>| {
index.or_else(|| {
if attrs.dynamic {
if attrs.dynamic || attrs.unindexed_variants {
None
} else {
Some(index_allocator.next_const_index(discriminant))
Expand All @@ -90,7 +98,15 @@ pub(crate) fn derive_enum<'a>(
};

let variant_label = |label: Option<LabelValue>, ident: &Ident| {
if attrs.dynamic {
if attrs.dynamic || attrs.unlabeled_variants {
None
} else {
Some(label_or_ident(label, ident))
}
};

let unit_variant_label = |label: Option<LabelValue>, ident: &Ident| {
if attrs.unlabeled_variants {
None
} else {
Some(label_or_ident(label, ident))
Expand Down Expand Up @@ -142,7 +158,7 @@ pub(crate) fn derive_enum<'a>(
stream_tag(
quote!(#ident :: #variant_ident),
attrs.tag(),
Some(label_or_ident(attrs.label(), variant_ident)),
unit_variant_label(attrs.label(), variant_ident),
variant_index(attrs.index(), discriminant),
)
}
Expand Down

0 comments on commit 072cff7

Please sign in to comment.