@@ -13,8 +13,8 @@ use syn::{
13
13
parse_macro_input,
14
14
punctuated:: Punctuated ,
15
15
token:: { Comma , Paren , Where } ,
16
- Data , DataStruct , DeriveInput , Field , Fields , Generics , Ident , Index , Member , Meta , NestedMeta ,
17
- Path ,
16
+ Attribute , Data , DataStruct , DeriveInput , Field , Fields , Generics , Ident , Index , Member , Meta ,
17
+ NestedMeta , Path ,
18
18
} ;
19
19
20
20
#[ derive( Default ) ]
@@ -45,11 +45,47 @@ enum DeriveType {
45
45
static REFLECT_ATTRIBUTE_NAME : & str = "reflect" ;
46
46
static REFLECT_VALUE_ATTRIBUTE_NAME : & str = "reflect_value" ;
47
47
48
+ fn active_fields ( punctuated : & Punctuated < Field , Comma > ) -> impl Iterator < Item = ( & Field , usize ) > {
49
+ punctuated. iter ( ) . enumerate ( ) . filter_map ( |( idx, field) | {
50
+ field
51
+ . attrs
52
+ . iter ( )
53
+ . find ( |attr| * attr. path . get_ident ( ) . as_ref ( ) . unwrap ( ) == REFLECT_ATTRIBUTE_NAME )
54
+ . map ( |attr| {
55
+ syn:: custom_keyword!( ignore) ;
56
+ attr. parse_args :: < Option < ignore > > ( )
57
+ . expect ( "Invalid 'property' attribute format." )
58
+ . is_none ( )
59
+ } )
60
+ . unwrap_or ( true )
61
+ . then ( || ( field, idx) )
62
+ } )
63
+ }
64
+
65
+ fn reflect_attrs ( attrs : & [ Attribute ] ) -> ( ReflectAttrs , Option < DeriveType > ) {
66
+ for attribute in attrs. iter ( ) . filter_map ( |attr| attr. parse_meta ( ) . ok ( ) ) {
67
+ if let Meta :: List ( meta_list) = attribute {
68
+ if let Some ( ident) = meta_list. path . get_ident ( ) {
69
+ if ident == REFLECT_ATTRIBUTE_NAME {
70
+ return ( ReflectAttrs :: from_nested_metas ( & meta_list. nested ) , None ) ;
71
+ } else if ident == REFLECT_VALUE_ATTRIBUTE_NAME {
72
+ return (
73
+ ReflectAttrs :: from_nested_metas ( & meta_list. nested ) ,
74
+ Some ( DeriveType :: Value ) ,
75
+ ) ;
76
+ }
77
+ }
78
+ }
79
+ }
80
+
81
+ Default :: default ( )
82
+ }
83
+
48
84
#[ proc_macro_derive( Reflect , attributes( reflect, reflect_value, module) ) ]
49
85
pub fn derive_reflect ( input : TokenStream ) -> TokenStream {
50
86
let ast = parse_macro_input ! ( input as DeriveInput ) ;
51
87
let unit_struct_punctuated = Punctuated :: new ( ) ;
52
- let ( fields, mut derive_type) = match & ast. data {
88
+ let ( fields, derive_type) = match & ast. data {
53
89
Data :: Struct ( DataStruct {
54
90
fields : Fields :: Named ( fields) ,
55
91
..
@@ -65,66 +101,14 @@ pub fn derive_reflect(input: TokenStream) -> TokenStream {
65
101
_ => ( & unit_struct_punctuated, DeriveType :: Value ) ,
66
102
} ;
67
103
68
- let fields_and_args = fields
69
- . iter ( )
70
- . enumerate ( )
71
- . map ( |( i, f) | {
72
- (
73
- f,
74
- f. attrs
75
- . iter ( )
76
- . find ( |a| * a. path . get_ident ( ) . as_ref ( ) . unwrap ( ) == REFLECT_ATTRIBUTE_NAME )
77
- . map ( |a| {
78
- syn:: custom_keyword!( ignore) ;
79
- let mut attribute_args = PropAttributeArgs { ignore : None } ;
80
- a. parse_args_with ( |input : ParseStream | {
81
- if input. parse :: < Option < ignore > > ( ) ?. is_some ( ) {
82
- attribute_args. ignore = Some ( true ) ;
83
- return Ok ( ( ) ) ;
84
- }
85
- Ok ( ( ) )
86
- } )
87
- . expect ( "Invalid 'property' attribute format." ) ;
88
-
89
- attribute_args
90
- } ) ,
91
- i,
92
- )
93
- } )
94
- . collect :: < Vec < ( & Field , Option < PropAttributeArgs > , usize ) > > ( ) ;
95
- let active_fields = fields_and_args
96
- . iter ( )
97
- . filter ( |( _field, attrs, _i) | {
98
- attrs. is_none ( )
99
- || match attrs. as_ref ( ) . unwrap ( ) . ignore {
100
- Some ( ignore) => !ignore,
101
- None => true ,
102
- }
103
- } )
104
- . map ( |( f, _attr, i) | ( * f, * i) )
105
- . collect :: < Vec < ( & Field , usize ) > > ( ) ;
104
+ let active_fields = active_fields ( & fields) . collect :: < Vec < _ > > ( ) ;
105
+
106
+ let ( reflect_attrs, modified_derive_type) = reflect_attrs ( & ast. attrs ) ;
107
+ let derive_type = modified_derive_type. unwrap_or ( derive_type) ;
106
108
107
109
let bevy_reflect_path = BevyManifest :: default ( ) . get_path ( "bevy_reflect" ) ;
108
110
let type_name = & ast. ident ;
109
111
110
- let mut reflect_attrs = ReflectAttrs :: default ( ) ;
111
- for attribute in ast. attrs . iter ( ) . filter_map ( |attr| attr. parse_meta ( ) . ok ( ) ) {
112
- let meta_list = if let Meta :: List ( meta_list) = attribute {
113
- meta_list
114
- } else {
115
- continue ;
116
- } ;
117
-
118
- if let Some ( ident) = meta_list. path . get_ident ( ) {
119
- if ident == REFLECT_ATTRIBUTE_NAME {
120
- reflect_attrs = ReflectAttrs :: from_nested_metas ( & meta_list. nested ) ;
121
- } else if ident == REFLECT_VALUE_ATTRIBUTE_NAME {
122
- derive_type = DeriveType :: Value ;
123
- reflect_attrs = ReflectAttrs :: from_nested_metas ( & meta_list. nested ) ;
124
- }
125
- }
126
- }
127
-
128
112
let registration_data = & reflect_attrs. data ;
129
113
let get_type_registration_impl = impl_get_type_registration (
130
114
type_name,
0 commit comments