1
- use proc_macro :: TokenStream ;
1
+ use proc_macro2 :: TokenStream ;
2
2
use quote:: { format_ident, quote} ;
3
- use syn:: { parse_quote, Ident , ItemStruct , Type } ;
3
+ use syn:: { parse_quote, Field , Ident , ItemStruct , Type } ;
4
4
5
5
use crate :: Result ;
6
6
7
7
pub ( crate ) fn impl_joined_value ( input_struct : & ItemStruct ) -> Result < TokenStream > {
8
8
let struct_ident = & input_struct. ident ;
9
9
let ( impl_generics, ty_generics, where_clause) = input_struct. generics . split_for_impl ( ) ;
10
- let ( field_ident, field_type) : ( Vec < _ > , Vec < _ > ) =
11
- get_fields_map ( & input_struct. fields ) ?. into_iter ( ) . unzip ( ) ;
10
+ let ( field_ident, field_type, _) = get_fields_map ( & input_struct. fields ) ?;
12
11
let struct_buffer_ident = format_ident ! ( "__bevy_impulse_{}_Buffers" , struct_ident) ;
13
12
14
13
let buffer_struct: ItemStruct = parse_quote ! {
@@ -33,13 +32,14 @@ pub(crate) fn impl_joined_value(input_struct: &ItemStruct) -> Result<TokenStream
33
32
34
33
impl #impl_generics #struct_ident #ty_generics #where_clause {
35
34
fn select_buffers(
35
+ builder: & mut :: bevy_impulse:: Builder ,
36
36
#(
37
- #field_ident: :: bevy_impulse:: Buffer <#field_type>,
37
+ #field_ident: impl :: bevy_impulse:: Bufferable < BufferType = :: bevy_impulse :: Buffer <#field_type> >,
38
38
) *
39
39
) -> #struct_buffer_ident #ty_generics {
40
40
#struct_buffer_ident {
41
41
#(
42
- #field_ident,
42
+ #field_ident: #field_ident . into_buffer ( builder ) ,
43
43
) *
44
44
}
45
45
}
@@ -53,18 +53,52 @@ pub(crate) fn impl_joined_value(input_struct: &ItemStruct) -> Result<TokenStream
53
53
Ok ( gen. into ( ) )
54
54
}
55
55
56
- fn get_fields_map ( fields : & syn:: Fields ) -> Result < Vec < ( & Ident , & Type ) > > {
56
+ struct FieldConfig {
57
+ buffer_type : TokenStream ,
58
+ }
59
+
60
+ impl FieldConfig {
61
+ fn from_field ( field : & Field ) -> Self {
62
+ let ty = & field. ty ;
63
+ let mut buffer_type = quote ! { :: bevy_impulse:: Buffer <#ty> } ;
64
+
65
+ let attr = field
66
+ . attrs
67
+ . iter ( )
68
+ . find ( |attr| attr. path ( ) . is_ident ( "bevy_impulse" ) ) ;
69
+
70
+ if let Some ( attr) = attr {
71
+ attr. parse_nested_meta ( |meta| {
72
+ if meta. path . is_ident ( "buffer_type" ) {
73
+ buffer_type = meta. value ( ) ?. parse ( ) ?;
74
+ }
75
+ Ok ( ( ) )
76
+ } )
77
+ // panic if attribute is malformed, this will result in a compile error
78
+ . unwrap ( ) ;
79
+ }
80
+
81
+ Self { buffer_type }
82
+ }
83
+ }
84
+
85
+ fn get_fields_map ( fields : & syn:: Fields ) -> Result < ( Vec < & Ident > , Vec < & Type > , Vec < FieldConfig > ) > {
57
86
match fields {
58
87
syn:: Fields :: Named ( data) => {
59
- let mut idents_types = Vec :: with_capacity ( data. named . len ( ) ) ;
88
+ let mut idents = Vec :: new ( ) ;
89
+ let mut types = Vec :: new ( ) ;
90
+ let mut configs = Vec :: new ( ) ;
60
91
for field in & data. named {
61
92
let ident = field
62
93
. ident
63
94
. as_ref ( )
64
95
. ok_or ( "expected named fields" . to_string ( ) ) ?;
65
- idents_types. push ( ( ident, & field. ty ) ) ;
96
+ let config = FieldConfig :: from_field ( field) ;
97
+ idents. push ( ident) ;
98
+ types. push ( & field. ty ) ;
99
+ configs. push ( config) ;
66
100
}
67
- Ok ( idents_types )
101
+ Ok ( ( idents , types , configs ) )
68
102
}
69
103
_ => return Err ( "expected named fields" . to_string ( ) ) ,
70
104
}
@@ -79,8 +113,7 @@ fn impl_buffer_map_layout(
79
113
) -> Result < proc_macro2:: TokenStream > {
80
114
let struct_ident = & buffer_struct. ident ;
81
115
let ( impl_generics, ty_generics, where_clause) = buffer_struct. generics . split_for_impl ( ) ;
82
- let ( field_ident, field_type) : ( Vec < _ > , Vec < _ > ) =
83
- get_fields_map ( & item_struct. fields ) ?. into_iter ( ) . unzip ( ) ;
116
+ let ( field_ident, field_type, _) = get_fields_map ( & item_struct. fields ) ?;
84
117
let map_key: Vec < String > = field_ident. iter ( ) . map ( |v| v. to_string ( ) ) . collect ( ) ;
85
118
86
119
Ok ( quote ! {
@@ -121,8 +154,7 @@ fn impl_joined(
121
154
let struct_ident = & joined_struct. ident ;
122
155
let item_struct_ident = & item_struct. ident ;
123
156
let ( impl_generics, ty_generics, where_clause) = item_struct. generics . split_for_impl ( ) ;
124
- let ( field_ident, _) : ( Vec < _ > , Vec < _ > ) =
125
- get_fields_map ( & item_struct. fields ) ?. into_iter ( ) . unzip ( ) ;
157
+ let ( field_ident, _, _) = get_fields_map ( & item_struct. fields ) ?;
126
158
127
159
Ok ( quote ! {
128
160
impl #impl_generics :: bevy_impulse:: Joined for #struct_ident #ty_generics #where_clause {
0 commit comments