1
1
use proc_macro2:: { Span , TokenStream } ;
2
- use quote:: quote;
2
+ use quote:: { format_ident , quote} ;
3
3
use syn:: { DataEnum , Ident } ;
4
4
5
5
use crate :: context:: Ctxt ;
@@ -44,51 +44,17 @@ pub(crate) fn implement(cx: &Ctxt<'_>, en: &DataEnum) -> Result<TokenStream, ()>
44
44
Span :: call_site ( ) ,
45
45
) ;
46
46
47
- let mut len = Vec :: new ( ) ;
48
- let mut is_empty = Vec :: new ( ) ;
49
- let mut pattern = Vec :: new ( ) ;
50
- let mut names = Vec :: new ( ) ;
51
- let mut fields = Vec :: new ( ) ;
52
- let mut field_inits = Vec :: new ( ) ;
53
- let mut contains_key = Vec :: new ( ) ;
54
- let mut get = Vec :: new ( ) ;
55
- let mut get_mut = Vec :: new ( ) ;
56
- let mut insert = Vec :: new ( ) ;
57
- let mut remove = Vec :: new ( ) ;
58
- let mut retain = Vec :: new ( ) ;
59
- let mut keys_iter_init = Vec :: new ( ) ;
60
- let mut iter_init = Vec :: new ( ) ;
61
- let mut entry = Vec :: new ( ) ;
47
+ let count = en. variants . len ( ) ;
48
+ let mut variants = Vec :: with_capacity ( count) ;
49
+ let mut names = Vec :: with_capacity ( count) ;
50
+ let mut field_inits = Vec :: with_capacity ( count) ;
62
51
63
52
for ( index, variant) in en. variants . iter ( ) . enumerate ( ) {
64
- let var = & variant. ident ;
65
- let name = Ident :: new ( & format ! ( "f{}" , index) , Span :: call_site ( ) ) ;
66
-
67
- len. push ( quote ! ( usize :: from( #option:: is_some( #name) ) ) ) ;
68
- is_empty. push ( quote ! ( #option:: is_none( #name) ) ) ;
69
53
field_inits. push ( quote ! ( #option:: None ) ) ;
70
- fields. push ( quote ! ( #option<V >) ) ;
71
- pattern. push ( quote ! ( #ident:: #var) ) ;
72
- contains_key. push ( quote ! ( #option:: is_some( #name) ) ) ;
73
- get. push ( quote ! ( #option:: as_ref( #name) ) ) ;
74
- get_mut. push ( quote ! ( #option:: as_mut( #name) ) ) ;
75
- insert. push ( quote ! ( #mem:: replace( #name, #option:: Some ( value) ) ) ) ;
76
- remove. push ( quote ! ( #mem:: take( #name) ) ) ;
77
- retain. push ( quote ! {
78
- if let Some ( val) = #option:: as_mut( #name) {
79
- if !func( #ident:: #var, val) {
80
- * #name = None ;
81
- }
82
- }
83
- } ) ;
84
- keys_iter_init. push ( quote ! ( if #name. is_some( ) { Some ( #ident:: #var) } else { None } ) ) ;
85
- iter_init. push ( quote ! ( ( #ident:: #var, #name) ) ) ;
86
- names. push ( name. clone ( ) ) ;
87
- entry. push ( quote ! ( option_to_entry( #name, key) ) ) ;
54
+ variants. push ( & variant. ident ) ;
55
+ names. push ( format_ident ! ( "_{}" , index) ) ;
88
56
}
89
57
90
- let count = en. variants . len ( ) ;
91
-
92
58
let entry_impl = if cfg ! ( feature = "entry" ) {
93
59
quote ! {
94
60
#vis struct VacantEntry <#lt, V > {
@@ -165,7 +131,7 @@ pub(crate) fn implement(cx: &Ctxt<'_>, en: &DataEnum) -> Result<TokenStream, ()>
165
131
let [ #( #names) , * ] = & mut self . data;
166
132
167
133
match key {
168
- #( #pattern => #entry , ) *
134
+ #( #ident :: #variants => option_to_entry ( #names , key ) , ) *
169
135
}
170
136
}
171
137
}
@@ -310,21 +276,21 @@ pub(crate) fn implement(cx: &Ctxt<'_>, en: &DataEnum) -> Result<TokenStream, ()>
310
276
#[ inline]
311
277
fn len( & self ) -> usize {
312
278
let [ #( #names) , * ] = & self . data;
313
- 0 #( + #len ) *
279
+ 0 #( + usize :: from ( #option :: is_some ( #names ) ) ) *
314
280
}
315
281
316
282
#[ inline]
317
283
fn is_empty( & self ) -> bool {
318
284
let [ #( #names) , * ] = & self . data;
319
- true #( && #is_empty ) *
285
+ true #( && #option :: is_none ( #names ) ) *
320
286
}
321
287
322
288
#[ inline]
323
289
fn insert( & mut self , key: #ident, value: V ) -> #option<V > {
324
290
let [ #( #names) , * ] = & mut self . data;
325
291
326
292
match key {
327
- #( #pattern => #insert , ) *
293
+ #( #ident :: #variants => #mem :: replace ( #names , #option :: Some ( value ) ) , ) *
328
294
}
329
295
}
330
296
@@ -333,7 +299,7 @@ pub(crate) fn implement(cx: &Ctxt<'_>, en: &DataEnum) -> Result<TokenStream, ()>
333
299
let [ #( #names) , * ] = & self . data;
334
300
335
301
match value {
336
- #( #pattern => #contains_key , ) *
302
+ #( #ident :: #variants => #option :: is_some ( #names ) , ) *
337
303
}
338
304
}
339
305
@@ -342,7 +308,7 @@ pub(crate) fn implement(cx: &Ctxt<'_>, en: &DataEnum) -> Result<TokenStream, ()>
342
308
let [ #( #names) , * ] = & self . data;
343
309
344
310
match value {
345
- #( #pattern => #get , ) *
311
+ #( #ident :: #variants => #option :: as_ref ( #names ) , ) *
346
312
}
347
313
}
348
314
@@ -351,7 +317,7 @@ pub(crate) fn implement(cx: &Ctxt<'_>, en: &DataEnum) -> Result<TokenStream, ()>
351
317
let [ #( #names) , * ] = & mut self . data;
352
318
353
319
match value {
354
- #( #pattern => #get_mut , ) *
320
+ #( #ident :: #variants => #option :: as_mut ( #names ) , ) *
355
321
}
356
322
}
357
323
@@ -360,7 +326,7 @@ pub(crate) fn implement(cx: &Ctxt<'_>, en: &DataEnum) -> Result<TokenStream, ()>
360
326
let [ #( #names) , * ] = & mut self . data;
361
327
362
328
match value {
363
- #( #pattern => #remove , ) *
329
+ #( #ident :: #variants => #mem :: take ( #names ) , ) *
364
330
}
365
331
}
366
332
@@ -370,7 +336,12 @@ pub(crate) fn implement(cx: &Ctxt<'_>, en: &DataEnum) -> Result<TokenStream, ()>
370
336
F : FnMut ( #ident, & mut V ) -> bool
371
337
{
372
338
let [ #( #names) , * ] = & mut self . data;
373
- #( #retain) *
339
+
340
+ #( if let Some ( val) = #option:: as_mut( #names) {
341
+ if !func( #ident:: #variants, val) {
342
+ * #names = None ;
343
+ }
344
+ } ) *
374
345
}
375
346
376
347
#[ inline]
@@ -381,13 +352,13 @@ pub(crate) fn implement(cx: &Ctxt<'_>, en: &DataEnum) -> Result<TokenStream, ()>
381
352
#[ inline]
382
353
fn iter( & self ) -> Self :: Iter <' _> {
383
354
let [ #( #names) , * ] = & self . data;
384
- #iterator:: flat_map( #into_iter( [ #( #iter_init ) , * ] ) , |( k, v) | #option:: Some ( ( k, #option:: as_ref( v) ?) ) )
355
+ #iterator:: flat_map( #into_iter( [ #( ( #ident :: #variants , #names ) ) , * ] ) , |( k, v) | #option:: Some ( ( k, #option:: as_ref( v) ?) ) )
385
356
}
386
357
387
358
#[ inline]
388
359
fn keys( & self ) -> Self :: Keys <' _> {
389
360
let [ #( #names) , * ] = & self . data;
390
- #iterator:: flatten( #into_iter( [ #( #keys_iter_init ) , * ] ) )
361
+ #iterator:: flatten( #into_iter( [ #( if #names . is_some ( ) { Some ( #ident :: #variants ) } else { None } ) , * ] ) )
391
362
}
392
363
393
364
#[ inline]
@@ -398,7 +369,7 @@ pub(crate) fn implement(cx: &Ctxt<'_>, en: &DataEnum) -> Result<TokenStream, ()>
398
369
#[ inline]
399
370
fn iter_mut( & mut self ) -> Self :: IterMut <' _> {
400
371
let [ #( #names) , * ] = & mut self . data;
401
- #iterator:: flat_map( #into_iter( [ #( #iter_init ) , * ] ) , |( k, v) | #option:: Some ( ( k, #option:: as_mut( v) ?) ) )
372
+ #iterator:: flat_map( #into_iter( [ #( ( #ident :: #variants , #names ) ) , * ] ) , |( k, v) | #option:: Some ( ( k, #option:: as_mut( v) ?) ) )
402
373
}
403
374
404
375
#[ inline]
@@ -409,7 +380,7 @@ pub(crate) fn implement(cx: &Ctxt<'_>, en: &DataEnum) -> Result<TokenStream, ()>
409
380
#[ inline]
410
381
fn into_iter( self ) -> Self :: IntoIter {
411
382
let [ #( #names) , * ] = self . data;
412
- #iterator:: flat_map( #into_iter( [ #( #iter_init ) , * ] ) , |( k, v) | #option:: Some ( ( k, v?) ) )
383
+ #iterator:: flat_map( #into_iter( [ #( ( #ident :: #variants , #names ) ) , * ] ) , |( k, v) | #option:: Some ( ( k, v?) ) )
413
384
}
414
385
}
415
386
0 commit comments