1
+ use std:: {
2
+ collections:: HashMap ,
3
+ iter:: { self , FromIterator } ,
4
+ } ;
5
+
1
6
use attributes:: { IdentList , NestedMetaList } ;
2
- use darling:: util:: Override ;
3
- use darling:: FromMeta ;
7
+ use darling:: { export:: NestedMeta , util:: Override , FromMeta } ;
4
8
use from:: {
5
9
generate_from_enum_trait_impl_for_ref, generate_from_variant_trait_impl,
6
10
generate_from_variant_trait_impl_for_ref,
@@ -10,11 +14,9 @@ use macros::generate_all_map_macros;
10
14
use proc_macro:: TokenStream ;
11
15
use proc_macro2:: { Span , TokenStream as TokenStream2 } ;
12
16
use quote:: { format_ident, quote, ToTokens } ;
13
- use std:: collections:: HashMap ;
14
- use std:: iter:: { self , FromIterator } ;
15
17
use syn:: {
16
- parse_macro_input, Attribute , AttributeArgs , Expr , Field , GenericParam , Ident , ItemStruct ,
17
- Lifetime , LifetimeDef , Type , TypeGenerics , TypeParamBound ,
18
+ parse_macro_input, Attribute , Expr , Field , GenericParam , Ident , ItemStruct , Lifetime ,
19
+ LifetimeParam , Type , TypeGenerics , TypeParamBound ,
18
20
} ;
19
21
20
22
mod attributes;
@@ -82,6 +84,7 @@ struct FieldOpts {
82
84
getter : Option < GetterOpts > ,
83
85
#[ darling( default ) ]
84
86
partial_getter : Option < GetterOpts > ,
87
+ no_getter : darling:: util:: Flag ,
85
88
}
86
89
87
90
/// Getter configuration for a specific field
@@ -135,6 +138,7 @@ struct FieldData {
135
138
only_combinations : Vec < VariantKey > ,
136
139
getter_opts : GetterOpts ,
137
140
partial_getter_opts : GetterOpts ,
141
+ no_getter : bool ,
138
142
is_common : bool ,
139
143
}
140
144
@@ -143,6 +147,10 @@ impl FieldData {
143
147
self . is_common
144
148
}
145
149
150
+ fn no_getter ( & self ) -> bool {
151
+ self . no_getter
152
+ }
153
+
146
154
/// Checks whether this field should be included in creating
147
155
/// partial getters for the given type name.
148
156
fn exists_in_meta ( & self , type_name : & Ident ) -> bool {
@@ -170,7 +178,10 @@ struct VariantKey {
170
178
171
179
#[ proc_macro_attribute]
172
180
pub fn superstruct ( args : TokenStream , input : TokenStream ) -> TokenStream {
173
- let attr_args = parse_macro_input ! ( args as AttributeArgs ) ;
181
+ let attr_args = match NestedMeta :: parse_meta_list ( args. into ( ) ) {
182
+ Ok ( args) => args,
183
+ Err ( err) => return err. to_compile_error ( ) . into ( ) ,
184
+ } ;
174
185
let item = parse_macro_input ! ( input as ItemStruct ) ;
175
186
176
187
let type_name = & item. ident ;
@@ -229,10 +240,7 @@ pub fn superstruct(args: TokenStream, input: TokenStream) -> TokenStream {
229
240
. attrs
230
241
. iter ( )
231
242
. filter ( |attr| is_superstruct_attr ( attr) )
232
- . map ( |attr| {
233
- let meta = attr. parse_meta ( ) . unwrap ( ) ;
234
- FieldOpts :: from_meta ( & meta) . unwrap ( )
235
- } )
243
+ . map ( |attr| FieldOpts :: from_meta ( & attr. meta ) . unwrap ( ) )
236
244
. next ( )
237
245
. unwrap_or_default ( ) ;
238
246
@@ -292,6 +300,12 @@ pub fn superstruct(args: TokenStream, input: TokenStream) -> TokenStream {
292
300
panic ! ( "can't set `flatten` and `getter` on the same field" ) ;
293
301
} else if field_opts. flatten . is_some ( ) && field_opts. partial_getter . is_some ( ) {
294
302
panic ! ( "can't set `flatten` and `partial_getter` on the same field" ) ;
303
+ } else if field_opts. flatten . is_some ( ) && field_opts. no_getter . is_present ( ) {
304
+ panic ! ( "can't set `flatten` and `no_getter` on the same field" )
305
+ } else if field_opts. getter . is_some ( ) && field_opts. no_getter . is_present ( ) {
306
+ panic ! ( "can't set `getter` and `no_getter` on the same field" )
307
+ } else if field_opts. partial_getter . is_some ( ) && field_opts. no_getter . is_present ( ) {
308
+ panic ! ( "can't set `partial_getter` and `no_getter` on the same field" )
295
309
}
296
310
297
311
let getter_opts = field_opts. getter . unwrap_or_default ( ) ;
@@ -395,6 +409,7 @@ pub fn superstruct(args: TokenStream, input: TokenStream) -> TokenStream {
395
409
only_combinations : vec ! [ variant_key. clone( ) ] ,
396
410
getter_opts : <_ >:: default ( ) ,
397
411
partial_getter_opts,
412
+ no_getter : false ,
398
413
is_common : false ,
399
414
} ) ;
400
415
@@ -418,6 +433,7 @@ pub fn superstruct(args: TokenStream, input: TokenStream) -> TokenStream {
418
433
. collect_vec ( ) ,
419
434
getter_opts,
420
435
partial_getter_opts,
436
+ no_getter : field_opts. no_getter . is_present ( ) ,
421
437
is_common,
422
438
} ) ;
423
439
}
@@ -444,8 +460,7 @@ pub fn superstruct(args: TokenStream, input: TokenStream) -> TokenStream {
444
460
. map_or ( & [ ] [ ..] , |attrs| & attrs. metas ) ;
445
461
let spatt = specific_struct_attributes
446
462
. iter ( )
447
- . chain ( specific_struct_attributes_meta. iter ( ) )
448
- . unique ( ) ;
463
+ . chain ( specific_struct_attributes_meta. iter ( ) ) ;
449
464
450
465
let variant_code = quote ! {
451
466
#(
@@ -556,7 +571,7 @@ fn generate_wrapper_enums(
556
571
let mut ref_ty_decl_generics = decl_generics. clone ( ) ;
557
572
ref_ty_decl_generics. params . insert (
558
573
0 ,
559
- GenericParam :: Lifetime ( LifetimeDef :: new ( ref_ty_lifetime. clone ( ) ) ) ,
574
+ GenericParam :: Lifetime ( LifetimeParam :: new ( ref_ty_lifetime. clone ( ) ) ) ,
560
575
) ;
561
576
562
577
// If no lifetime bound exists for a generic param, inject one.
@@ -603,7 +618,7 @@ fn generate_wrapper_enums(
603
618
let mut ref_mut_ty_decl_generics = decl_generics. clone ( ) ;
604
619
ref_mut_ty_decl_generics. params . insert (
605
620
0 ,
606
- GenericParam :: Lifetime ( LifetimeDef :: new ( ref_mut_ty_lifetime. clone ( ) ) ) ,
621
+ GenericParam :: Lifetime ( LifetimeParam :: new ( ref_mut_ty_lifetime. clone ( ) ) ) ,
607
622
) ;
608
623
let ( ref_mut_impl_generics, ref_mut_ty_generics, _) =
609
624
& ref_mut_ty_decl_generics. split_for_impl ( ) ;
@@ -629,19 +644,19 @@ fn generate_wrapper_enums(
629
644
// Construct the main impl block.
630
645
let getters = fields
631
646
. iter ( )
632
- . filter ( |f| f. is_common ( ) )
647
+ . filter ( |f| f. is_common ( ) && !f . no_getter ( ) )
633
648
. map ( |field_data| make_field_getter ( type_name, variant_names, field_data, None , is_meta) ) ;
634
649
635
650
let mut_getters = fields
636
651
. iter ( )
637
- . filter ( |f| f. is_common ( ) && !f. getter_opts . no_mut )
652
+ . filter ( |f| f. is_common ( ) && !f. no_getter ( ) && !f . getter_opts . no_mut )
638
653
. map ( |field_data| {
639
654
make_mut_field_getter ( type_name, variant_names, field_data, None , is_meta)
640
655
} ) ;
641
656
642
657
let partial_getters = fields
643
658
. iter ( )
644
- . filter ( |f| !f. is_common ( ) )
659
+ . filter ( |f| !f. is_common ( ) && !f . no_getter ( ) )
645
660
. filter ( |f| is_meta || f. exists_in_meta ( type_name) )
646
661
. cartesian_product ( & [ false , true ] )
647
662
. flat_map ( |( field_data, mutability) | {
@@ -713,19 +728,22 @@ fn generate_wrapper_enums(
713
728
output_items. push ( impl_block. into ( ) ) ;
714
729
715
730
// Construct the impl block for the *Ref type.
716
- let ref_getters = fields. iter ( ) . filter ( |f| f. is_common ( ) ) . map ( |field_data| {
717
- make_field_getter (
718
- & ref_ty_name,
719
- variant_names,
720
- field_data,
721
- Some ( & ref_ty_lifetime) ,
722
- is_meta,
723
- )
724
- } ) ;
731
+ let ref_getters = fields
732
+ . iter ( )
733
+ . filter ( |f| f. is_common ( ) && !f. no_getter ( ) )
734
+ . map ( |field_data| {
735
+ make_field_getter (
736
+ & ref_ty_name,
737
+ variant_names,
738
+ field_data,
739
+ Some ( & ref_ty_lifetime) ,
740
+ is_meta,
741
+ )
742
+ } ) ;
725
743
726
744
let ref_partial_getters = fields
727
745
. iter ( )
728
- . filter ( |f| !f. is_common ( ) )
746
+ . filter ( |f| !f. is_common ( ) && !f . no_getter ( ) )
729
747
. filter ( |f| is_meta || f. exists_in_meta ( type_name) )
730
748
. flat_map ( |field_data| {
731
749
let field_variants = & field_data. only_combinations ;
@@ -762,7 +780,7 @@ fn generate_wrapper_enums(
762
780
// Construct the impl block for the *RefMut type.
763
781
let ref_mut_getters = fields
764
782
. iter ( )
765
- . filter ( |f| f. is_common ( ) && !f. getter_opts . no_mut )
783
+ . filter ( |f| f. is_common ( ) && !f. no_getter ( ) && !f . getter_opts . no_mut )
766
784
. map ( |field_data| {
767
785
make_mut_field_getter (
768
786
& ref_mut_ty_name,
@@ -775,7 +793,7 @@ fn generate_wrapper_enums(
775
793
776
794
let ref_mut_partial_getters = fields
777
795
. iter ( )
778
- . filter ( |f| !f. is_common ( ) && !f. partial_getter_opts . no_mut )
796
+ . filter ( |f| !f. is_common ( ) && !f. no_getter ( ) && !f . partial_getter_opts . no_mut )
779
797
. filter ( |f| is_meta || f. exists_in_meta ( type_name) )
780
798
. flat_map ( |field_data| {
781
799
let field_variants = & field_data. only_combinations ;
@@ -1123,7 +1141,7 @@ fn is_superstruct_attr(attr: &Attribute) -> bool {
1123
1141
1124
1142
/// Predicate for determining whether an attribute has the given `ident` as its path.
1125
1143
fn is_attr_with_ident ( attr : & Attribute , ident : & str ) -> bool {
1126
- attr. path
1144
+ attr. path ( )
1127
1145
. get_ident ( )
1128
1146
. map_or ( false , |attr_ident| * attr_ident == ident)
1129
1147
}
0 commit comments