1
1
use std:: num:: ParseIntError ;
2
2
3
- use crate :: { Array , Reflect , ReflectMut , ReflectRef } ;
3
+ use crate :: { Array , Reflect , ReflectMut , ReflectRef , VariantType } ;
4
4
use thiserror:: Error ;
5
5
6
6
/// An error returned from a failed path string query.
@@ -29,6 +29,8 @@ pub enum ReflectPathError<'a> {
29
29
IndexParseError ( #[ from] ParseIntError ) ,
30
30
#[ error( "failed to downcast to the path result to the given type" ) ]
31
31
InvalidDowncast ,
32
+ #[ error( "expected either a struct variant or tuple variant, but found a unit variant" ) ]
33
+ InvalidVariantAccess { index : usize , accessor : & ' a str } ,
32
34
}
33
35
34
36
/// A trait which allows nested values to be retrieved with path strings.
@@ -280,6 +282,29 @@ fn read_field<'r, 'p>(
280
282
} ,
281
283
) ?)
282
284
}
285
+ ReflectRef :: Enum ( reflect_enum) => match reflect_enum. variant_type ( ) {
286
+ VariantType :: Struct => {
287
+ Ok ( reflect_enum
288
+ . field ( field)
289
+ . ok_or ( ReflectPathError :: InvalidField {
290
+ index : current_index,
291
+ field,
292
+ } ) ?)
293
+ }
294
+ VariantType :: Tuple => {
295
+ let tuple_index = field. parse :: < usize > ( ) ?;
296
+ Ok ( reflect_enum
297
+ . field_at ( tuple_index)
298
+ . ok_or ( ReflectPathError :: InvalidField {
299
+ index : current_index,
300
+ field,
301
+ } ) ?)
302
+ }
303
+ _ => Err ( ReflectPathError :: InvalidVariantAccess {
304
+ index : current_index,
305
+ accessor : field,
306
+ } ) ,
307
+ } ,
283
308
_ => Err ( ReflectPathError :: ExpectedStruct {
284
309
index : current_index,
285
310
} ) ,
@@ -309,6 +334,29 @@ fn read_field_mut<'r, 'p>(
309
334
} ,
310
335
) ?)
311
336
}
337
+ ReflectMut :: Enum ( reflect_enum) => match reflect_enum. variant_type ( ) {
338
+ VariantType :: Struct => {
339
+ Ok ( reflect_enum
340
+ . field_mut ( field)
341
+ . ok_or ( ReflectPathError :: InvalidField {
342
+ index : current_index,
343
+ field,
344
+ } ) ?)
345
+ }
346
+ VariantType :: Tuple => {
347
+ let tuple_index = field. parse :: < usize > ( ) ?;
348
+ Ok ( reflect_enum. field_at_mut ( tuple_index) . ok_or (
349
+ ReflectPathError :: InvalidField {
350
+ index : current_index,
351
+ field,
352
+ } ,
353
+ ) ?)
354
+ }
355
+ _ => Err ( ReflectPathError :: InvalidVariantAccess {
356
+ index : current_index,
357
+ accessor : field,
358
+ } ) ,
359
+ } ,
312
360
_ => Err ( ReflectPathError :: ExpectedStruct {
313
361
index : current_index,
314
362
} ) ,
@@ -416,6 +464,9 @@ mod tests {
416
464
x : B ,
417
465
y : Vec < C > ,
418
466
z : D ,
467
+ unit_variant : F ,
468
+ tuple_variant : F ,
469
+ struct_variant : F ,
419
470
}
420
471
421
472
#[ derive( Reflect ) ]
@@ -435,6 +486,13 @@ mod tests {
435
486
#[ derive( Reflect ) ]
436
487
struct E ( f32 , usize ) ;
437
488
489
+ #[ derive( Reflect , FromReflect , PartialEq , Debug ) ]
490
+ enum F {
491
+ Unit ,
492
+ Tuple ( u32 , u32 ) ,
493
+ Struct { value : char } ,
494
+ }
495
+
438
496
let mut a = A {
439
497
w : 1 ,
440
498
x : B {
@@ -443,6 +501,9 @@ mod tests {
443
501
} ,
444
502
y : vec ! [ C { baz: 1.0 } , C { baz: 2.0 } ] ,
445
503
z : D ( E ( 10.0 , 42 ) ) ,
504
+ unit_variant : F :: Unit ,
505
+ tuple_variant : F :: Tuple ( 123 , 321 ) ,
506
+ struct_variant : F :: Struct { value : 'm' } ,
446
507
} ;
447
508
448
509
assert_eq ! ( * a. get_path:: <usize >( "w" ) . unwrap( ) , 1 ) ;
@@ -451,9 +512,16 @@ mod tests {
451
512
assert_eq ! ( * a. get_path:: <f32 >( "y[1].baz" ) . unwrap( ) , 2.0 ) ;
452
513
assert_eq ! ( * a. get_path:: <usize >( "z.0.1" ) . unwrap( ) , 42 ) ;
453
514
515
+ assert_eq ! ( * a. get_path:: <F >( "unit_variant" ) . unwrap( ) , F :: Unit ) ;
516
+ assert_eq ! ( * a. get_path:: <u32 >( "tuple_variant.1" ) . unwrap( ) , 321 ) ;
517
+ assert_eq ! ( * a. get_path:: <char >( "struct_variant.value" ) . unwrap( ) , 'm' ) ;
518
+
454
519
* a. get_path_mut :: < f32 > ( "y[1].baz" ) . unwrap ( ) = 3.0 ;
455
520
assert_eq ! ( a. y[ 1 ] . baz, 3.0 ) ;
456
521
522
+ * a. get_path_mut :: < u32 > ( "tuple_variant.0" ) . unwrap ( ) = 1337 ;
523
+ assert_eq ! ( a. tuple_variant, F :: Tuple ( 1337 , 321 ) ) ;
524
+
457
525
assert_eq ! (
458
526
a. path( "x.notreal" ) . err( ) . unwrap( ) ,
459
527
ReflectPathError :: InvalidField {
@@ -462,6 +530,14 @@ mod tests {
462
530
}
463
531
) ;
464
532
533
+ assert_eq ! (
534
+ a. path( "unit_variant.0" ) . err( ) . unwrap( ) ,
535
+ ReflectPathError :: InvalidVariantAccess {
536
+ index: 13 ,
537
+ accessor: "0"
538
+ }
539
+ ) ;
540
+
465
541
assert_eq ! (
466
542
a. path( "x.." ) . err( ) . unwrap( ) ,
467
543
ReflectPathError :: ExpectedIdent { index: 2 }
0 commit comments