@@ -77,7 +77,7 @@ fn generate_fields_diff(
77
77
let right = format_ident ! ( "r{}" , field_idx) ;
78
78
79
79
let push = if let Some ( _) = ident {
80
- quote ! { ctx. push_field( #ident_as_str) ; }
80
+ quote ! { ctx. push_field( #field_idx , # ident_as_str) ; }
81
81
} else {
82
82
quote ! { ctx. push_field_index( #field_idx) ; }
83
83
} ;
@@ -170,7 +170,7 @@ fn ok_fields(fields : &syn::Fields) -> Result<Vec<ParsedField>, proc_macro::Toke
170
170
}
171
171
}
172
172
173
- fn generate_arms ( name : & syn:: Ident , variant : Option < & syn:: Ident > , fields : & syn:: Fields , matching : bool )
173
+ fn generate_arms ( name : & syn:: Ident , variant : Option < ( u16 , & syn:: Ident ) > , fields : & syn:: Fields , matching : bool )
174
174
-> Result < ( Vec < proc_macro2:: TokenStream > , Vec < proc_macro2:: TokenStream > ) ,
175
175
proc_macro2:: TokenStream >
176
176
{
@@ -182,14 +182,15 @@ fn generate_arms(name: &syn::Ident, variant: Option<&syn::Ident>, fields: &syn::
182
182
matching,
183
183
) ;
184
184
let ( left, right) = enum_fields ( & fields, false ) ;
185
- let variant_specifier = if let Some ( id ) = variant {
185
+ let variant_specifier = if let Some ( ( _ , id ) ) = variant {
186
186
quote ! { :: #id}
187
187
} else {
188
188
quote ! { }
189
189
} ;
190
190
191
- let variant_as_str = variant. map ( |i| i. to_string ( ) ) ;
192
- let push_variant = variant. map ( |_| quote ! { ctx. push_variant( #variant_as_str) ; } ) ;
191
+ let variant_idx = variant. map ( |( i, _) | i) ;
192
+ let variant_as_str = variant. map ( |( _, i) | i. to_string ( ) ) ;
193
+ let push_variant = variant. map ( |_| quote ! { ctx. push_variant( #variant_idx, #variant_as_str) ; } ) ;
193
194
let pop_variant = variant. map ( |_| quote ! { ctx. pop_path_element( ) ?; } ) ;
194
195
195
196
let left = if matching {
@@ -259,6 +260,16 @@ fn generate_arms(name: &syn::Ident, variant: Option<&syn::Ident>, fields: &syn::
259
260
}
260
261
261
262
if let Some ( _) = variant {
263
+ apply_match_arms. push ( quote ! {
264
+ ( & mut #name #variant_specifier #left, Some ( serde_diff:: DiffPathElementValue :: EnumVariantIndex ( #variant_idx) ) ) => {
265
+ while let Some ( element) = ctx. next_path_element( seq) ? {
266
+ match element {
267
+ #( #apply_fn_field_handlers) *
268
+ _ => ctx. skip_value( seq) ?
269
+ }
270
+ }
271
+ }
272
+ } ) ;
262
273
apply_match_arms. push ( quote ! {
263
274
( & mut #name #variant_specifier #left, Some ( serde_diff:: DiffPathElementValue :: EnumVariant ( variant) ) ) if variant == #variant_as_str => {
264
275
while let Some ( element) = ctx. next_path_element( seq) ? {
@@ -299,8 +310,8 @@ fn generate(
299
310
let has_variants = match & input. data {
300
311
Data :: Enum ( e) => {
301
312
for matching in & [ true , false ] {
302
- for v in & e. variants {
303
- let ( diff, apply) = generate_arms ( & struct_args. ident , Some ( & v. ident ) , & v. fields , * matching) ?;
313
+ for ( i , v ) in e. variants . iter ( ) . enumerate ( ) {
314
+ let ( diff, apply) = generate_arms ( & struct_args. ident , Some ( ( i as u16 , & v. ident ) ) , & v. fields , * matching) ?;
304
315
diff_match_arms. extend ( diff) ;
305
316
apply_match_arms. extend ( apply) ;
306
317
}
0 commit comments