@@ -30,31 +30,57 @@ pub(crate) enum VariantFieldConfig {
30
30
Index ( usize ) ,
31
31
}
32
32
33
- #[ derive( Clone , Default , Debug ) ]
33
+ #[ derive( Clone , Default , PartialEq , Eq , Debug ) ]
34
+ pub ( crate ) struct MacroSelectionConfig {
35
+ pub idents : Vec < syn:: Ident > ,
36
+ }
37
+
38
+ impl MacroSelectionConfig {
39
+ pub fn is_empty ( & self ) -> bool {
40
+ self . idents . is_empty ( )
41
+ }
42
+
43
+ pub fn contains ( & self , name : & str ) -> bool {
44
+ self . idents . iter ( ) . any ( |ident| ident == name)
45
+ }
46
+
47
+ pub fn extend_idents ( & mut self , iter : impl IntoIterator < Item = syn:: Ident > ) {
48
+ self . idents . extend ( iter) ;
49
+ }
50
+
51
+ pub ( crate ) fn idents ( & self ) -> & [ syn:: Ident ] {
52
+ & self . idents
53
+ }
54
+ }
55
+
56
+ pub ( crate ) type EnumExcludeConfig = MacroSelectionConfig ;
57
+ pub ( crate ) type VariantExcludeConfig = MacroSelectionConfig ;
58
+ pub ( crate ) type VariantIncludeConfig = MacroSelectionConfig ;
59
+
60
+ #[ derive( Clone , Default ) ]
34
61
pub ( crate ) struct EnumConfig {
35
62
// #[enumcapsulate(exclude(…))]
36
- pub exclude : Option < Vec < syn :: Ident > > ,
63
+ pub exclude : Option < EnumExcludeConfig > ,
37
64
}
38
65
39
66
impl EnumConfig {
40
67
pub fn is_excluded ( & self , name : & str ) -> bool {
41
- if let Some ( excluded) = & self . exclude {
42
- return excluded. iter ( ) . any ( |ident| ident == name) ;
43
- } else {
44
- false
45
- }
68
+ self . exclude
69
+ . as_ref ( )
70
+ . map ( |excluded| excluded. contains ( name) )
71
+ . unwrap_or ( false )
46
72
}
47
73
}
48
74
49
- #[ derive( Clone , Default , Debug ) ]
75
+ #[ derive( Clone , Default ) ]
50
76
pub ( crate ) struct VariantConfig {
51
77
// #[enumcapsulate(exclude(…))]
52
- pub exclude : Option < Vec < syn :: Ident > > ,
78
+ pub exclude : Option < VariantExcludeConfig > ,
53
79
54
80
// #[enumcapsulate(include(…))]
55
- pub include : Option < Vec < syn :: Ident > > ,
81
+ pub include : Option < VariantIncludeConfig > ,
56
82
57
- // #[enumcapsulate(field(… = … ))]
83
+ // #[enumcapsulate(field(…))]
58
84
pub field : Option < VariantFieldConfig > ,
59
85
}
60
86
@@ -73,49 +99,48 @@ impl VariantConfig {
73
99
}
74
100
75
101
pub fn is_excluded_explicitly ( & self , name : & str ) -> bool {
76
- if let Some ( excluded) = & self . exclude {
77
- if excluded. is_empty ( ) {
78
- if let Some ( included) = & self . include {
79
- return !included. iter ( ) . any ( |ident| ident == name) ;
80
- } else {
81
- return true ;
82
- }
83
- }
102
+ let Some ( excluded) = & self . exclude else {
103
+ return false ;
104
+ } ;
84
105
85
- excluded. iter ( ) . any ( |ident| ident == name)
86
- } else {
87
- false
106
+ if excluded. is_empty ( ) {
107
+ if let Some ( included) = & self . include {
108
+ return !included. contains ( name) ;
109
+ } else {
110
+ return true ;
111
+ }
88
112
}
113
+
114
+ excluded. contains ( name)
89
115
}
90
116
91
117
pub fn is_included_explicitly ( & self , name : & str ) -> bool {
92
- if let Some ( included) = & self . include {
93
- if included. is_empty ( ) {
94
- if let Some ( excluded) = & self . exclude {
95
- return !excluded. iter ( ) . any ( |ident| ident == name) ;
96
- } else {
97
- return true ;
98
- }
99
- }
118
+ let Some ( included) = & self . include else {
119
+ return false ;
120
+ } ;
100
121
101
- included. iter ( ) . any ( |ident| ident == name)
102
- } else {
103
- false
122
+ if included. is_empty ( ) {
123
+ if let Some ( excluded) = & self . exclude {
124
+ return !excluded. contains ( name) ;
125
+ } else {
126
+ return true ;
127
+ }
104
128
}
129
+
130
+ included. contains ( name)
105
131
}
106
132
}
107
133
108
- pub ( crate ) fn config_for_enum_with_attrs (
109
- enum_attrs : & [ syn:: Attribute ] ,
110
- ) -> Result < EnumConfig , syn:: Error > {
134
+ pub ( crate ) fn config_for_enum ( enum_item : & syn:: ItemEnum ) -> Result < EnumConfig , syn:: Error > {
111
135
let mut config = EnumConfig :: default ( ) ;
112
136
113
- parse_enumcapsulate_attrs ( enum_attrs , |meta| {
137
+ parse_enumcapsulate_attrs ( & enum_item . attrs , |meta| {
114
138
if meta. path . is_ident ( attr:: EXCLUDE ) {
115
139
// #[enumcapsulate(exclude(…))]
116
140
117
141
let mut exclude = config. exclude . take ( ) . unwrap_or_default ( ) ;
118
- exclude. extend ( macro_idents_for_enum ( & meta) ?. into_iter ( ) ) ;
142
+ exclude. extend_idents ( macro_selection_config_for_enum ( & meta) ?. idents ) ;
143
+
119
144
config. exclude = Some ( exclude) ;
120
145
} else {
121
146
return Err ( meta. error ( "unrecognized attribute" ) ) ;
@@ -141,17 +166,19 @@ pub(crate) fn config_for_variant(variant: &syn::Variant) -> Result<VariantConfig
141
166
// #[enumcapsulate(exclude(…))]
142
167
143
168
let mut exclude = config. exclude . take ( ) . unwrap_or_default ( ) ;
144
- let conflicting = config. include . as_deref ( ) . unwrap_or ( & [ ] ) ;
145
169
146
- exclude. extend ( macro_idents_for_variant ( & meta, conflicting) ?. into_iter ( ) ) ;
170
+ let opposite = config. include . as_ref ( ) ;
171
+ exclude. extend_idents ( macro_selection_config_for_variant ( & meta, opposite) ?. idents ) ;
172
+
147
173
config. exclude = Some ( exclude) ;
148
174
} else if meta. path . is_ident ( attr:: INCLUDE ) {
149
175
// #[enumcapsulate(include(…))]
150
176
151
177
let mut include = config. include . take ( ) . unwrap_or_default ( ) ;
152
- let conflicting = config. exclude . as_deref ( ) . unwrap_or ( & [ ] ) ;
153
178
154
- include. extend ( macro_idents_for_variant ( & meta, conflicting) ?. into_iter ( ) ) ;
179
+ let opposite: Option < & MacroSelectionConfig > = config. exclude . as_ref ( ) ;
180
+ include. extend_idents ( macro_selection_config_for_variant ( & meta, opposite) ?. idents ) ;
181
+
155
182
config. include = Some ( include) ;
156
183
} else if meta. path . is_ident ( attr:: FIELD ) {
157
184
// #[enumcapsulate(field(…))]
@@ -233,29 +260,30 @@ pub(crate) fn parse_enumcapsulate_attrs(
233
260
Ok ( ( ) )
234
261
}
235
262
236
- pub ( crate ) fn macro_idents_for_enum (
263
+ pub ( crate ) fn macro_selection_config_for_enum (
237
264
meta : & syn:: meta:: ParseNestedMeta < ' _ > ,
238
- ) -> Result < Vec < syn :: Ident > , syn:: Error > {
265
+ ) -> Result < MacroSelectionConfig , syn:: Error > {
239
266
let idents = parse_idents_from_meta_list ( meta) ?;
240
267
241
268
let recognized = RECOGNIZED_ENUM_LEVEL_MACROS ;
242
269
ensure_only_recognized_ident_names ( & idents, recognized) ?;
243
270
244
- Ok ( idents)
271
+ Ok ( MacroSelectionConfig { idents } )
245
272
}
246
273
247
- pub ( crate ) fn macro_idents_for_variant (
274
+ pub ( crate ) fn macro_selection_config_for_variant (
248
275
meta : & syn:: meta:: ParseNestedMeta < ' _ > ,
249
- conflict_list : & [ syn :: Ident ] ,
250
- ) -> Result < Vec < syn :: Ident > , syn:: Error > {
276
+ opposite : Option < & MacroSelectionConfig > ,
277
+ ) -> Result < MacroSelectionConfig , syn:: Error > {
251
278
let idents = parse_idents_from_meta_list ( meta) ?;
252
279
253
280
let recognized = RECOGNIZED_VARIANT_LEVEL_MACROS ;
254
281
ensure_only_recognized_ident_names ( & idents, recognized) ?;
255
282
283
+ let conflict_list = opposite. map ( |config| config. idents ( ) ) . unwrap_or ( & [ ] ) ;
256
284
ensure_no_conflicting_idents ( & idents, conflict_list) ?;
257
285
258
- Ok ( idents)
286
+ Ok ( MacroSelectionConfig { idents } )
259
287
}
260
288
261
289
pub ( crate ) fn ensure_only_recognized_ident_names (
0 commit comments