1
1
use std:: collections:: HashSet ;
2
2
3
- use proc_macro2:: { Span , TokenStream } ;
3
+ use proc_macro2:: { Literal , TokenStream } ;
4
4
use proc_macro_error:: { abort, proc_macro_error} ;
5
5
use quote:: { quote, ToTokens } ;
6
6
use syn:: {
@@ -165,52 +165,91 @@ fn generate_path_serializations(fields: &[&Field]) -> Vec<TokenStream> {
165
165
fields
166
166
. iter ( )
167
167
. filter ( |field| !field. attributes . contains ( & FieldAttribute :: Leaf ) )
168
- . map ( |field| {
169
- let identifier = & field. identifier ;
170
- let pattern = identifier. to_string ( ) ;
171
- quote ! {
172
- #pattern => self . #identifier. serialize_path( suffix, serializer)
168
+ . map ( |field| match & field. identifier {
169
+ IdentOrEnumIndex :: Ident ( identifier) => {
170
+ let pattern = identifier. to_string ( ) ;
171
+ quote ! {
172
+ #pattern => self . #identifier. serialize_path( suffix, serializer)
173
+ }
174
+ }
175
+ IdentOrEnumIndex :: EnumIndex ( index) => {
176
+ let pattern = index. to_string ( ) ;
177
+ let tuple_accessor = Literal :: usize_unsuffixed ( * index) ;
178
+ quote ! {
179
+ #pattern => self . #tuple_accessor. serialize_path( suffix, serializer)
180
+ }
173
181
}
174
182
} )
175
183
. collect ( )
176
184
}
177
185
178
186
fn generate_serde_serializations ( fields : & [ & Field ] ) -> Vec < TokenStream > {
179
- fields. iter ( ) . map ( |field| {
180
- let identifier = & field. identifier ;
181
- let pattern = identifier. to_string ( ) ;
182
- quote ! {
183
- #pattern => serde:: Serialize :: serialize( & self . #identifier, serializer) . map_err( serialize_hierarchy:: Error :: SerializationFailed )
184
- }
187
+ fields. iter ( ) . map ( |field|
188
+ match & field. identifier {
189
+ IdentOrEnumIndex :: Ident ( identifier) => {
190
+ let pattern = identifier. to_string ( ) ;
191
+ quote ! {
192
+ #pattern => serde:: Serialize :: serialize( & self . #identifier, serializer) . map_err( serialize_hierarchy:: Error :: SerializationFailed )
193
+ }
194
+ } ,
195
+ IdentOrEnumIndex :: EnumIndex ( index) =>{
196
+ let pattern = index. to_string ( ) ;
197
+ let tuple_accessor = Literal :: usize_unsuffixed ( * index) ;
198
+ quote ! {
199
+ #pattern => serde:: Serialize :: serialize( & self . #tuple_accessor, serializer) . map_err( serialize_hierarchy:: Error :: SerializationFailed )
200
+ }
201
+ } ,
185
202
} ) . collect ( )
186
203
}
187
204
188
205
fn generate_path_deserializations ( fields : & [ & Field ] ) -> Vec < TokenStream > {
189
206
fields
190
207
. iter ( )
191
208
. filter ( |field| !field. attributes . contains ( & FieldAttribute :: Leaf ) )
192
- . map ( |field| {
193
- let identifier = & field. identifier ;
194
- let pattern = identifier. to_string ( ) ;
195
- quote ! {
196
- #pattern => self . #identifier. deserialize_path( suffix, deserializer)
209
+ . map ( |field| match & field. identifier {
210
+ IdentOrEnumIndex :: Ident ( identifier) => {
211
+ let pattern = identifier. to_string ( ) ;
212
+ quote ! {
213
+ #pattern => self . #identifier. deserialize_path( suffix, deserializer)
214
+ }
215
+ }
216
+ IdentOrEnumIndex :: EnumIndex ( index) => {
217
+ let pattern = index. to_string ( ) ;
218
+ let tuple_accessor = Literal :: usize_unsuffixed ( * index) ;
219
+ quote ! {
220
+ #pattern => self . #tuple_accessor. deserialize_path( suffix, deserializer)
221
+ }
197
222
}
198
223
} )
199
224
. collect ( )
200
225
}
201
226
202
227
fn generate_serde_deserializations ( fields : & [ & Field ] ) -> Vec < TokenStream > {
203
- fields. iter ( ) . map ( |field| {
204
- let identifier = & field. identifier ;
205
- let pattern = identifier. to_string ( ) ;
206
- let ty = & field. ty ;
207
- quote ! {
208
- #pattern => {
209
- self . #identifier = <#ty as serde:: Deserialize >:: deserialize( deserializer) . map_err( serialize_hierarchy:: Error :: DeserializationFailed ) ?;
210
- Ok ( ( ) )
211
- }
228
+ fields. iter ( ) . map ( |field|
229
+ match & field. identifier {
230
+ IdentOrEnumIndex :: Ident ( identifier) => {
231
+ let pattern = identifier. to_string ( ) ;
232
+ let ty = & field. ty ;
233
+ quote ! {
234
+ #pattern => {
235
+ self . #identifier = <#ty as serde:: Deserialize >:: deserialize( deserializer) . map_err( serialize_hierarchy:: Error :: DeserializationFailed ) ?;
236
+ Ok ( ( ) )
237
+ }
212
238
213
- }
239
+ }
240
+ } ,
241
+ IdentOrEnumIndex :: EnumIndex ( index) => {
242
+ let pattern = index. to_string ( ) ;
243
+ let tuple_accessor = Literal :: usize_unsuffixed ( * index) ;
244
+ let ty = & field. ty ;
245
+ quote ! {
246
+ #pattern => {
247
+ self . #tuple_accessor = <#ty as serde:: Deserialize >:: deserialize( deserializer) . map_err( serialize_hierarchy:: Error :: DeserializationFailed ) ?;
248
+ Ok ( ( ) )
249
+ }
250
+
251
+ }
252
+ }
214
253
} ) . collect ( )
215
254
}
216
255
@@ -219,7 +258,10 @@ fn generate_path_exists_getters(fields: &[&Field]) -> Vec<TokenStream> {
219
258
. iter ( )
220
259
. filter ( |field| !field. attributes . contains ( & FieldAttribute :: Leaf ) )
221
260
. map ( |field| {
222
- let pattern = field. identifier . to_string ( ) ;
261
+ let pattern = match & field. identifier {
262
+ IdentOrEnumIndex :: Ident ( identifier) => identifier. to_string ( ) ,
263
+ IdentOrEnumIndex :: EnumIndex ( index) => index. to_string ( ) ,
264
+ } ;
223
265
let ty = & field. ty ;
224
266
quote ! {
225
267
#pattern => <#ty as serialize_hierarchy:: SerializeHierarchy >:: exists( suffix)
@@ -232,7 +274,10 @@ fn generate_field_exists_getters(fields: &[&Field]) -> Vec<TokenStream> {
232
274
fields
233
275
. iter ( )
234
276
. map ( |field| {
235
- let pattern = field. identifier . to_string ( ) ;
277
+ let pattern = match & field. identifier {
278
+ IdentOrEnumIndex :: Ident ( identifier) => identifier. to_string ( ) ,
279
+ IdentOrEnumIndex :: EnumIndex ( index) => index. to_string ( ) ,
280
+ } ;
236
281
quote ! {
237
282
#pattern => true
238
283
}
@@ -244,7 +289,10 @@ fn generate_field_chains(fields: &[&Field]) -> Vec<TokenStream> {
244
289
fields
245
290
. iter ( )
246
291
. map ( |field| {
247
- let name_string = field. identifier . to_string ( ) ;
292
+ let name_string = match & field. identifier {
293
+ IdentOrEnumIndex :: Ident ( identifier) => identifier. to_string ( ) ,
294
+ IdentOrEnumIndex :: EnumIndex ( index) => index. to_string ( ) ,
295
+ } ;
248
296
quote ! {
249
297
fields. insert( format!( "{prefix}{}" , #name_string) ) ;
250
298
}
@@ -257,7 +305,10 @@ fn generate_path_field_chains(fields: &[&Field]) -> Vec<TokenStream> {
257
305
. iter ( )
258
306
. filter ( |field| !field. attributes . contains ( & FieldAttribute :: Leaf ) )
259
307
. map ( |field| {
260
- let field_name = & field. identifier . to_string ( ) ;
308
+ let field_name = match & field. identifier {
309
+ IdentOrEnumIndex :: Ident ( identifier) => identifier. to_string ( ) ,
310
+ IdentOrEnumIndex :: EnumIndex ( index) =>index. to_string ( ) ,
311
+ } ;
261
312
let ty = & field. ty ;
262
313
quote ! {
263
314
<#ty as serialize_hierarchy:: SerializeHierarchy >:: fill_fields( fields, & format!( "{prefix}{}." , #field_name) ) ;
@@ -319,10 +370,16 @@ enum FieldAttribute {
319
370
Leaf ,
320
371
}
321
372
373
+ #[ derive( Debug ) ]
374
+ enum IdentOrEnumIndex {
375
+ Ident ( Ident ) ,
376
+ EnumIndex ( usize ) ,
377
+ }
378
+
322
379
#[ derive( Debug ) ]
323
380
struct Field {
324
381
attributes : HashSet < FieldAttribute > ,
325
- identifier : Ident ,
382
+ identifier : IdentOrEnumIndex ,
326
383
ty : Type ,
327
384
}
328
385
@@ -368,10 +425,10 @@ fn read_fields(input: &DataStruct) -> Vec<Field> {
368
425
}
369
426
} )
370
427
. collect ( ) ;
371
- let identifier = field
372
- . ident
373
- . clone ( )
374
- . unwrap_or ( Ident :: new ( & format ! ( "_{}" , field_index ) , Span :: call_site ( ) ) ) ;
428
+ let identifier = field. ident . clone ( ) . map_or_else (
429
+ || IdentOrEnumIndex :: EnumIndex ( field_index ) ,
430
+ |identifier| IdentOrEnumIndex :: Ident ( identifier ) ,
431
+ ) ;
375
432
let ty = field. ty . clone ( ) ;
376
433
Field {
377
434
attributes,
0 commit comments