Skip to content

Commit 9e6ce21

Browse files
committed
Simplify use of nested variant discriminants
(by removing the need for passing an explicit type name to the `#[enumcapsulate(discriminant(nested = …))]` variant attribute)
1 parent aa38911 commit 9e6ce21

File tree

13 files changed

+61
-46
lines changed

13 files changed

+61
-46
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Please make sure to add your changes to the appropriate categories:
2424

2525
### Changed
2626

27-
- n/a
27+
- Changed the `#[enumcapsulate(discriminant(nested))]` variant attribute into a value-less unit attribute (`nested`), removing the previously required explicit type argument (`nested = <Type>`).
2828

2929
### Deprecated
3030

macros/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ Specify a nested sub-discriminant type for the generated discriminant variant.
288288
289289
If you wish a discriminant variant generated by the `VariantDiscriminant`
290290
derive macro to be nested, then you can do so by use
291-
of an `#[enumcapsulate(discriminant(nested =))]` attribute:
291+
of an `#[enumcapsulate(discriminant(nested))]` attribute:
292292
293293
```rust
294294
#[derive(VariantDiscriminant)]
@@ -299,8 +299,8 @@ enum VariantA {
299299
300300
#[derive(VariantDiscriminant)]
301301
enum Enum {
302-
#[enumcapsulate(discriminant(nested = VariantADiscriminant))]
303-
VariantA(i32),
302+
#[enumcapsulate(discriminant(nested))]
303+
VariantA(VariantA),
304304
305305
VariantB { b: u32 },
306306
}

macros/src/config/for_variant.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
mod config;
22
mod discriminant;
33

4-
pub(crate) use self::config::VariantConfig;
5-
6-
use self::discriminant::DiscriminantConfig;
4+
pub(crate) use self::{config::*, discriminant::*};

macros/src/config/for_variant/discriminant.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::attr::{NAME, NESTED, VALUE};
66
pub(crate) struct DiscriminantConfig {
77
value: Option<syn::Expr>,
88
name: Option<syn::Ident>,
9-
nested: Option<syn::Path>,
9+
nested: bool,
1010
}
1111

1212
impl DiscriminantConfig {
@@ -19,8 +19,8 @@ impl DiscriminantConfig {
1919
if meta.path.is_ident(VALUE) {
2020
if self.value.is_some() {
2121
return Err(meta.error("`value = …` already specified"));
22-
} else if self.nested.is_some() {
23-
return Err(meta.error("conflicting with use of `nesting = …`"));
22+
} else if self.nested {
23+
return Err(meta.error("conflicting with use of `nesting`"));
2424
}
2525

2626
self.value = Some(meta.value()?.parse()?);
@@ -33,13 +33,13 @@ impl DiscriminantConfig {
3333
} else if meta.path.is_ident(NESTED) {
3434
if matches!(variant.fields, syn::Fields::Unit) {
3535
return Err(meta.error("no field found on variant"));
36-
} else if self.nested.is_some() {
37-
return Err(meta.error("`nested = …` already specified"));
36+
} else if self.nested {
37+
return Err(meta.error("`nested` already specified"));
3838
} else if self.value.is_some() {
3939
return Err(meta.error("conflicting with use of `value = …`"));
4040
}
4141

42-
self.nested = Some(meta.value()?.parse()?);
42+
self.nested = true;
4343
} else {
4444
return Err(meta.error("unsupported discriminant attribute"));
4545
}
@@ -56,7 +56,7 @@ impl DiscriminantConfig {
5656
self.name.as_ref()
5757
}
5858

59-
pub(crate) fn nested(&self) -> Option<&syn::Path> {
60-
self.nested.as_ref()
59+
pub(crate) fn nested(&self) -> bool {
60+
self.nested
6161
}
6262
}

macros/src/enum_deriver.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use proc_macro2::TokenStream as TokenStream2;
22
use quote::quote;
3-
use syn::{parse_quote_spanned, visit::Visit as _, Fields, Type, Variant};
3+
use syn::{parse_quote, parse_quote_spanned, visit::Visit as _, Fields, Type, Variant};
44

55
use crate::*;
66

@@ -562,10 +562,13 @@ impl EnumDeriver {
562562
for (variant, variant_config) in variants.into_iter().zip(variant_configs) {
563563
let variant_ident: &syn::Ident = &variant.ident;
564564

565+
let field_selection = variant_config.selected_field(&variant.fields)?;
566+
assert_eq!(field_selection.is_none(), variant.fields.is_empty());
567+
565568
let mut discriminant_variant_ident: syn::Ident = variant_ident.clone();
566569
let mut discriminant_variant_expr: Option<&syn::Expr> =
567570
variant.discriminant.as_ref().map(|(_, expr)| expr);
568-
let mut discriminant_variant_nested: Option<&syn::Path> = None;
571+
let mut discriminant_variant_nested: Option<syn::Type> = None;
569572

570573
if let Some(discriminant_config) = variant_config.discriminant() {
571574
if let Some(ident) = discriminant_config.ident() {
@@ -576,8 +579,13 @@ impl EnumDeriver {
576579
discriminant_variant_expr = Some(expr);
577580
}
578581

579-
if let Some(nested) = discriminant_config.nested() {
580-
discriminant_variant_nested = Some(nested);
582+
if discriminant_config.nested() {
583+
let (field, _) = field_selection.expect("no selected field found");
584+
let ty = &field.ty;
585+
let nested_type = parse_quote! {
586+
<#ty as ::enumcapsulate::VariantDiscriminant>::Discriminant
587+
};
588+
discriminant_variant_nested = Some(nested_type);
581589
}
582590
}
583591

@@ -597,9 +605,6 @@ impl EnumDeriver {
597605
#discriminant_variant_ident #variant_discriminant,
598606
});
599607

600-
let field_selection = variant_config.selected_field(&variant.fields)?;
601-
assert_eq!(field_selection.is_none(), variant.fields.is_empty());
602-
603608
let field_pattern = if variant_is_nested {
604609
let (field, index) = field_selection.unwrap();
605610
self.field_pattern(&variant.fields, (field, index))
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
error: no field found on variant
22
--> /tests/derive-tests/variant_discriminant/fail/nested_on_unit_variant.rs:5:34
33
|
4-
5 | #[enumcapsulate(discriminant(nested = VariantADiscriminant, value = 42))]
4+
5 | #[enumcapsulate(discriminant(nested, value = 42))]
55
| ^^^^^^
66
error: could not compile `<CRATE>` (bin "<BIN>") due to 1 previous error
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use enumcapsulate::VariantDiscriminant;
22
pub enum Enum {
3-
#[enumcapsulate(discriminant(nested = VariantADiscriminant, value = 42))]
3+
#[enumcapsulate(discriminant(nested, value = 42))]
44
VariantA,
55
}
66
fn main() {}

tests/derive-tests/variant_discriminant/fail/nested_on_unit_variant.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use enumcapsulate::VariantDiscriminant;
22

33
#[derive(VariantDiscriminant)]
44
pub enum Enum {
5-
#[enumcapsulate(discriminant(nested = VariantADiscriminant, value = 42))]
5+
#[enumcapsulate(discriminant(nested, value = 42))]
66
VariantA,
77
}
88

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
error: conflicting with use of `nesting = …`
2-
--> /tests/derive-tests/variant_discriminant/fail/nested_with_value.rs:11:65
1+
error: conflicting with use of `nesting`
2+
--> /tests/derive-tests/variant_discriminant/fail/nested_with_value.rs:11:42
33
|
4-
11 | #[enumcapsulate(discriminant(nested = VariantADiscriminant, value = 42))]
5-
| ^^^^^
4+
11 | #[enumcapsulate(discriminant(nested, value = 42))]
5+
| ^^^^^
66
error: could not compile `<CRATE>` (bin "<BIN>") due to 1 previous error

tests/derive-tests/variant_discriminant/fail/nested_with_value.out.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ impl ::enumcapsulate::VariantDiscriminant for VariantA {
8787
}
8888
}
8989
pub enum Enum {
90-
#[enumcapsulate(discriminant(nested = VariantADiscriminant, value = 42))]
90+
#[enumcapsulate(discriminant(nested, value = 42))]
9191
VariantA(VariantA),
9292
}
9393
fn main() {}

0 commit comments

Comments
 (0)