diff --git a/derive_macros/src/attr.rs b/derive_macros/src/attr.rs index 07d6bf7b..40014885 100644 --- a/derive_macros/src/attr.rs +++ b/derive_macros/src/attr.rs @@ -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. diff --git a/derive_macros/src/derive/derive_enum.rs b/derive_macros/src/derive/derive_enum.rs index 27e42260..c08bc6a0 100644 --- a/derive_macros/src/derive/derive_enum.rs +++ b/derive_macros/src/derive/derive_enum.rs @@ -17,6 +17,8 @@ pub(crate) struct EnumAttrs { tag: Option, label: Option, index: Option, + unlabeled_variants: bool, + unindexed_variants: bool, dynamic: bool, } @@ -29,6 +31,8 @@ impl EnumAttrs { &attr::LabelAttr, &attr::IndexAttr, &attr::DynamicAttr, + &attr::UnlabeledVariantsAttr, + &attr::UnindexedVariantsAttr, ], attrs, ); @@ -36,6 +40,8 @@ impl EnumAttrs { 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 { @@ -48,6 +54,8 @@ impl EnumAttrs { tag, label, index, + unlabeled_variants, + unindexed_variants, dynamic, } } @@ -81,7 +89,7 @@ pub(crate) fn derive_enum<'a>( let mut variant_index = |index: Option, discriminant: Option| { index.or_else(|| { - if attrs.dynamic { + if attrs.dynamic || attrs.unindexed_variants { None } else { Some(index_allocator.next_const_index(discriminant)) @@ -90,7 +98,15 @@ pub(crate) fn derive_enum<'a>( }; let variant_label = |label: Option, 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, ident: &Ident| { + if attrs.unlabeled_variants { None } else { Some(label_or_ident(label, ident)) @@ -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), ) }