Skip to content

Commit f0621f1

Browse files
committed
Remove potentially confusing #[enumcapsulate(include(…))] helper attributes
1 parent f9613fe commit f0621f1

File tree

5 files changed

+53
-254
lines changed

5 files changed

+53
-254
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Please make sure to add your changes to the appropriate categories:
2727
- Bumped MSRV from "1.74.0" to "1.78.0".
2828
- Made the enum-level `#[enumcapsulate(exclude(…))]` helper macros only have an effect on derives, when orchestrated through the `Encapsulate` derive macro.
2929
- Made `Encapsulate` derive macro no longer derive `VariantDiscriminant`.
30+
- Removed potentially confusing `#[enumcapsulate(include(…))]` helper attributes.
3031

3132
### Deprecated
3233

macros/README.md

Lines changed: 6 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,6 @@ enum Enum { /* ... */ }
5959
> your your particular use case then your can selectively opt them out by use of an
6060
> `#[enumcapsulate(exclude(…))]` attribute on the enum itself.
6161
>
62-
> You can even opt trait derives back in at the variant-level, by use of `#[enumcapsulate(include)]`
63-
> for previously opted-out derives, or individually by use of `#[enumcapsulate(include(…))]`:
64-
>
6562
> ```rust
6663
> #[derive(Encapsulate)]
6764
> #[enumcapsulate(exclude(From, TryInto))]
@@ -70,12 +67,14 @@ enum Enum { /* ... */ }
7067
> // due to existing enum-level attribute:
7168
> VariantA(VariantA),
7269
>
73-
> // Selectively re-included for all derives:
74-
> #[enumcapsulate(include)]
70+
> // Exclude derivation of any traits
71+
> // for this specific variant's type:
72+
> #[enumcapsulate(exclude)]
7573
> VariantB(VariantB),
7674
>
77-
> // Selectively re-included for `From` derive:
78-
> #[enumcapsulate(include(From))]
75+
> // Selectively exclude derivation of `From` trait
76+
> // for this specific variant's type:
77+
> #[enumcapsulate(exclude(From))]
7978
> VariantC(VariantC),
8079
> }
8180
> ```
@@ -110,32 +109,6 @@ then you can do so by use of an `#[enumcapsulate(exclude(…))]` attribute:
110109
enum Enum { /* ... */ }
111110
```
112111
113-
> [!TIP]
114-
> If you wish to opt all but a select few variants out of a trait's derive, then
115-
> you can do so by use of an `#[enumcapsulate(exclude(…))]` attribute on the enum,
116-
> together with a `#[enumcapsulate(include(…))]` attribute on the variant:
117-
>
118-
> ```rust
119-
> #[derive(Encapsulate)]
120-
> #[enumcapsulate(exclude(From, TryInto))]
121-
> enum Enum {
122-
> // Excluded from `From` and `TryInto` derives
123-
> // due to existing enum-level attribute:
124-
> VariantA(VariantA),
125-
>
126-
> // Selectively re-included for all derives:
127-
> #[enumcapsulate(include)]
128-
> VariantB(VariantB),
129-
>
130-
> // Selectively re-included for
131-
> // just the `From` derive:
132-
> #[enumcapsulate(include(From))]
133-
> VariantC(VariantC),
134-
>
135-
> // ...
136-
> }
137-
> ```
138-
139112
### Variant attributes
140113
141114
> [!NOTE]
@@ -170,71 +143,6 @@ enum Enum {
170143
}
171144
```
172145
173-
> [!TIP]
174-
> Combine the use of `#[enumcapsulate(exclude)]` with `#[enumcapsulate(include(…)]`
175-
> in order to exclude a variant from all but a select few derive macros.
176-
>
177-
> ```rust
178-
> // Exclude variant from all derives,
179-
> // then selectively re-include it for
180-
> // just the `From` and `TryInto` derives:
181-
> #[enumcapsulate(exclude)]
182-
> #[enumcapsulate(include(From, TryInto))]
183-
> ```
184-
185-
This attribute is recognized by the following variant-based derive macros:
186-
187-
- `AsVariant`
188-
- `AsVariantMut`
189-
- `AsVariantRef`
190-
- `FromVariant`
191-
- `IntoVariant`
192-
- `From`
193-
- `TryInto`
194-
195-
as well as the umbrella derive macro:
196-
197-
- `Encapsulate`
198-
199-
#### `#[enumcapsulate(include(…)]`
200-
201-
Include this variant for specific trait derivation (overriding existing uses of `#[enumcapsulate(exclude)]`).
202-
203-
- `#[enumcapsulate(include)]`
204-
205-
Include variant from *all* `enumcapsulate` derive macros.
206-
207-
- `#[enumcapsulate(include(…))]`
208-
209-
Include variant from specific `enumcapsulate` derive macros.
210-
211-
```rust
212-
#[derive(Encapsulate)]
213-
#[enumcapsulate(exclude(From, TryInto))]
214-
enum Enum {
215-
// Included by default.
216-
VariantA(VariantA),
217-
218-
// Selectively included for just
219-
// the `From` and `TryInto` derives:
220-
#[enumcapsulate(exclude)]
221-
#[enumcapsulate(include(From, TryInto))]
222-
VariantB(VariantB),
223-
}
224-
```
225-
226-
> [!NOTE]
227-
> The `#[enumcapsulate(include(…)]` variant has a higher precedence than `#[enumcapsulate(exclude)]`,
228-
> and thus acts as a selective override if both are present on a variant:
229-
>
230-
> ```rust
231-
> // Exclude variant from all derives,
232-
> // then selectively re-include it for
233-
> // just the `From` and `TryInto` derives:
234-
> #[enumcapsulate(exclude)]
235-
> #[enumcapsulate(include(From, TryInto))]
236-
> ```
237-
238146
This attribute is recognized by the following variant-based derive macros:
239147
240148
- `AsVariant`

macros/src/config.rs

Lines changed: 8 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,10 @@ impl MacroSelectionConfig {
4747
pub fn extend_idents(&mut self, iter: impl IntoIterator<Item = syn::Ident>) {
4848
self.idents.extend(iter);
4949
}
50-
51-
pub(crate) fn idents(&self) -> &[syn::Ident] {
52-
&self.idents
53-
}
5450
}
5551

5652
pub(crate) type EnumExcludeConfig = MacroSelectionConfig;
5753
pub(crate) type VariantExcludeConfig = MacroSelectionConfig;
58-
pub(crate) type VariantIncludeConfig = MacroSelectionConfig;
5954

6055
#[derive(Clone, Default)]
6156
pub(crate) struct EncapsulateEnumConfig {
@@ -84,56 +79,26 @@ pub(crate) struct VariantConfig {
8479
// #[enumcapsulate(exclude(…))]
8580
pub exclude: Option<VariantExcludeConfig>,
8681

87-
// #[enumcapsulate(include(…))]
88-
pub include: Option<VariantIncludeConfig>,
89-
9082
// #[enumcapsulate(field(…))]
9183
pub field: Option<VariantFieldConfig>,
9284
}
9385

9486
impl VariantConfig {
95-
pub fn is_excluded(&self, name: &str) -> bool {
96-
if self.is_included_explicitly(name) {
97-
return false;
98-
}
99-
100-
if self.is_excluded_explicitly(name) {
101-
return true;
102-
}
103-
104-
false
87+
#[allow(dead_code)]
88+
pub fn is_included(&self, name: &str) -> bool {
89+
!self.is_excluded(name)
10590
}
10691

107-
pub fn is_excluded_explicitly(&self, name: &str) -> bool {
92+
pub fn is_excluded(&self, name: &str) -> bool {
10893
let Some(excluded) = &self.exclude else {
10994
return false;
11095
};
11196

11297
if excluded.is_empty() {
113-
if let Some(included) = &self.include {
114-
return !included.contains(name);
115-
} else {
116-
return true;
117-
}
118-
}
119-
120-
excluded.contains(name)
121-
}
122-
123-
pub fn is_included_explicitly(&self, name: &str) -> bool {
124-
let Some(included) = &self.include else {
125-
return false;
126-
};
127-
128-
if included.is_empty() {
129-
if let Some(excluded) = &self.exclude {
130-
return !excluded.contains(name);
131-
} else {
132-
return true;
133-
}
98+
true
99+
} else {
100+
excluded.contains(name)
134101
}
135-
136-
included.contains(name)
137102
}
138103
}
139104

@@ -205,19 +170,9 @@ pub(crate) fn config_for_variant(variant: &syn::Variant) -> Result<VariantConfig
205170

206171
let mut exclude = config.exclude.take().unwrap_or_default();
207172

208-
let opposite = config.include.as_ref();
209-
exclude.extend_idents(macro_selection_config_for_variant(&meta, opposite)?.idents);
173+
exclude.extend_idents(macro_selection_config_for_variant(&meta)?.idents);
210174

211175
config.exclude = Some(exclude);
212-
} else if meta.path.is_ident(attr::INCLUDE) {
213-
// #[enumcapsulate(include(…))]
214-
215-
let mut include = config.include.take().unwrap_or_default();
216-
217-
let opposite: Option<&MacroSelectionConfig> = config.exclude.as_ref();
218-
include.extend_idents(macro_selection_config_for_variant(&meta, opposite)?.idents);
219-
220-
config.include = Some(include);
221176
} else if meta.path.is_ident(attr::FIELD) {
222177
// #[enumcapsulate(field(…))]
223178
meta.parse_nested_meta(|meta| {
@@ -311,16 +266,12 @@ pub(crate) fn macro_selection_config_for_enum(
311266

312267
pub(crate) fn macro_selection_config_for_variant(
313268
meta: &syn::meta::ParseNestedMeta<'_>,
314-
opposite: Option<&MacroSelectionConfig>,
315269
) -> Result<MacroSelectionConfig, syn::Error> {
316270
let idents = parse_idents_from_meta_list(meta)?;
317271

318272
let recognized = RECOGNIZED_VARIANT_LEVEL_MACROS;
319273
ensure_only_recognized_ident_names(&idents, recognized)?;
320274

321-
let conflict_list = opposite.map(|config| config.idents()).unwrap_or(&[]);
322-
ensure_no_conflicting_idents(&idents, conflict_list)?;
323-
324275
Ok(MacroSelectionConfig { idents })
325276
}
326277

@@ -350,32 +301,6 @@ pub(crate) fn ensure_only_recognized_ident_names(
350301
Ok(())
351302
}
352303

353-
pub(crate) fn ensure_no_conflicting_idents(
354-
idents: &[syn::Ident],
355-
conflicting: &[syn::Ident],
356-
) -> Result<(), syn::Error> {
357-
let mut error: Option<syn::Error> = None;
358-
359-
let conflicting = idents
360-
.iter()
361-
.filter(|&ident| conflicting.iter().any(|conflicting| ident == conflicting));
362-
363-
for ident in conflicting {
364-
let ident_err = syn::Error::new_spanned(ident, "conflicting macro derive");
365-
if let Some(error) = error.as_mut() {
366-
error.combine(ident_err);
367-
} else {
368-
error = Some(ident_err)
369-
}
370-
}
371-
372-
if let Some(err) = error {
373-
return Err(err);
374-
}
375-
376-
Ok(())
377-
}
378-
379304
pub(crate) fn parse_idents_from_meta_list(
380305
meta: &syn::meta::ParseNestedMeta<'_>,
381306
) -> Result<Vec<syn::Ident>, syn::Error> {

0 commit comments

Comments
 (0)