@@ -318,15 +318,23 @@ impl<'a, 'de> DeserializeSeed<'de> for TypedReflectDeserializer<'a> {
318
318
Ok ( Box :: new ( dynamic_tuple) )
319
319
}
320
320
TypeInfo :: Enum ( enum_info) => {
321
- let mut dynamic_enum = deserializer. deserialize_enum (
322
- enum_info. name ( ) ,
323
- enum_info. variant_names ( ) ,
324
- EnumVisitor {
321
+ let type_name = enum_info. type_name ( ) ;
322
+ let mut dynamic_enum = if type_name. starts_with ( "core::option::Option" ) {
323
+ deserializer. deserialize_option ( OptionVisitor {
325
324
enum_info,
326
325
registry : self . registry ,
327
- } ,
328
- ) ?;
329
- dynamic_enum. set_name ( enum_info. type_name ( ) . to_string ( ) ) ;
326
+ } ) ?
327
+ } else {
328
+ deserializer. deserialize_enum (
329
+ enum_info. name ( ) ,
330
+ enum_info. variant_names ( ) ,
331
+ EnumVisitor {
332
+ enum_info,
333
+ registry : self . registry ,
334
+ } ,
335
+ ) ?
336
+ } ;
337
+ dynamic_enum. set_name ( type_name. to_string ( ) ) ;
330
338
Ok ( Box :: new ( dynamic_enum) )
331
339
}
332
340
TypeInfo :: Value ( _) => {
@@ -588,16 +596,7 @@ impl<'a, 'de> Visitor<'de> for EnumVisitor<'a> {
588
596
) ?
589
597
. into ( ) ,
590
598
VariantInfo :: Tuple ( tuple_info) if tuple_info. field_len ( ) == 1 => {
591
- let field = tuple_info. field_at ( 0 ) . unwrap ( ) ;
592
- let type_info =
593
- self . registry
594
- . get_type_info ( field. type_id ( ) )
595
- . ok_or_else ( || {
596
- Error :: custom ( format_args ! (
597
- "no registration found for type {}" ,
598
- field. type_name( )
599
- ) )
600
- } ) ?;
599
+ let type_info = get_newtype_info ( tuple_info, self . registry ) ?;
601
600
let value = variant. newtype_variant_seed ( TypedReflectDeserializer {
602
601
type_info,
603
602
registry : self . registry ,
@@ -665,6 +664,54 @@ impl<'a, 'de> Visitor<'de> for TupleVariantVisitor<'a> {
665
664
}
666
665
}
667
666
667
+ struct OptionVisitor < ' a > {
668
+ enum_info : & ' static EnumInfo ,
669
+ registry : & ' a TypeRegistry ,
670
+ }
671
+
672
+ impl < ' a , ' de > Visitor < ' de > for OptionVisitor < ' a > {
673
+ type Value = DynamicEnum ;
674
+
675
+ fn expecting ( & self , formatter : & mut Formatter ) -> fmt:: Result {
676
+ formatter. write_str ( "reflected option value of type " ) ?;
677
+ formatter. write_str ( self . enum_info . type_name ( ) )
678
+ }
679
+
680
+ fn visit_some < D > ( self , deserializer : D ) -> Result < Self :: Value , D :: Error >
681
+ where
682
+ D : serde:: Deserializer < ' de > ,
683
+ {
684
+ let variant_info = self . enum_info . variant ( "Some" ) . unwrap ( ) ;
685
+ match variant_info {
686
+ VariantInfo :: Tuple ( tuple_info) if tuple_info. field_len ( ) == 1 => {
687
+ let type_info = get_newtype_info ( tuple_info, self . registry ) ?;
688
+ let de = TypedReflectDeserializer {
689
+ type_info,
690
+ registry : self . registry ,
691
+ } ;
692
+ let mut value = DynamicTuple :: default ( ) ;
693
+ value. insert_boxed ( de. deserialize ( deserializer) ?) ;
694
+ let mut option = DynamicEnum :: default ( ) ;
695
+ option. set_variant ( "Some" , value) ;
696
+ Ok ( option)
697
+ }
698
+ info => Err ( Error :: custom ( format_args ! (
699
+ "invalid variant, expected `Some` but got `{}`" ,
700
+ info. name( )
701
+ ) ) ) ,
702
+ }
703
+ }
704
+
705
+ fn visit_none < E > ( self ) -> Result < Self :: Value , E >
706
+ where
707
+ E : Error ,
708
+ {
709
+ let mut option = DynamicEnum :: default ( ) ;
710
+ option. set_variant ( "None" , ( ) ) ;
711
+ Ok ( option)
712
+ }
713
+ }
714
+
668
715
fn visit_struct < ' de , T , V > (
669
716
map : & mut V ,
670
717
info : & ' static T ,
@@ -732,6 +779,19 @@ where
732
779
Ok ( tuple)
733
780
}
734
781
782
+ fn get_newtype_info < E : Error > (
783
+ tuple_info : & ' static TupleVariantInfo ,
784
+ registry : & TypeRegistry ,
785
+ ) -> Result < & ' static TypeInfo , E > {
786
+ let field = tuple_info. field_at ( 0 ) . unwrap ( ) ;
787
+ registry. get_type_info ( field. type_id ( ) ) . ok_or_else ( || {
788
+ Error :: custom ( format_args ! (
789
+ "no registration found for type {}" ,
790
+ field. type_name( )
791
+ ) )
792
+ } )
793
+ }
794
+
735
795
fn get_type_info < E : de:: Error > (
736
796
type_id : TypeId ,
737
797
type_name : & str ,
@@ -950,6 +1010,71 @@ mod tests {
950
1010
assert_eq ! ( expected, output) ;
951
1011
}
952
1012
1013
+ #[ test]
1014
+ fn should_deserialize_option ( ) {
1015
+ #[ derive( Reflect , FromReflect , Debug , PartialEq ) ]
1016
+ struct OptionTest {
1017
+ none : Option < ( ) > ,
1018
+ simple : Option < String > ,
1019
+ complex : Option < SomeStruct > ,
1020
+ }
1021
+
1022
+ let expected = OptionTest {
1023
+ none : None ,
1024
+ simple : Some ( String :: from ( "Hello world!" ) ) ,
1025
+ complex : Some ( SomeStruct { foo : 123 } ) ,
1026
+ } ;
1027
+
1028
+ let mut registry = get_registry ( ) ;
1029
+ registry. register :: < OptionTest > ( ) ;
1030
+ registry. register :: < Option < ( ) > > ( ) ;
1031
+
1032
+ // === Normal === //
1033
+ let input = r#"{
1034
+ "bevy_reflect::serde::de::tests::should_deserialize_option::OptionTest": (
1035
+ none: None,
1036
+ simple: Some("Hello world!"),
1037
+ complex: Some((
1038
+ foo: 123,
1039
+ )),
1040
+ ),
1041
+ }"# ;
1042
+
1043
+ let reflect_deserializer = UntypedReflectDeserializer :: new ( & registry) ;
1044
+ let mut ron_deserializer = ron:: de:: Deserializer :: from_str ( input) . unwrap ( ) ;
1045
+ let dynamic_output = reflect_deserializer
1046
+ . deserialize ( & mut ron_deserializer)
1047
+ . unwrap ( ) ;
1048
+
1049
+ let output = <OptionTest as FromReflect >:: from_reflect ( dynamic_output. as_ref ( ) ) . unwrap ( ) ;
1050
+ assert_eq ! ( expected, output, "failed to deserialize Options" ) ;
1051
+
1052
+ // === Implicit Some === //
1053
+ let input = r#"
1054
+ #![enable(implicit_some)]
1055
+ {
1056
+ "bevy_reflect::serde::de::tests::should_deserialize_option::OptionTest": (
1057
+ none: None,
1058
+ simple: "Hello world!",
1059
+ complex: (
1060
+ foo: 123,
1061
+ ),
1062
+ ),
1063
+ }"# ;
1064
+
1065
+ let reflect_deserializer = UntypedReflectDeserializer :: new ( & registry) ;
1066
+ let mut ron_deserializer = ron:: de:: Deserializer :: from_str ( input) . unwrap ( ) ;
1067
+ let dynamic_output = reflect_deserializer
1068
+ . deserialize ( & mut ron_deserializer)
1069
+ . unwrap ( ) ;
1070
+
1071
+ let output = <OptionTest as FromReflect >:: from_reflect ( dynamic_output. as_ref ( ) ) . unwrap ( ) ;
1072
+ assert_eq ! (
1073
+ expected, output,
1074
+ "failed to deserialize Options with implicit Some"
1075
+ ) ;
1076
+ }
1077
+
953
1078
#[ test]
954
1079
fn enum_should_deserialize ( ) {
955
1080
#[ derive( Reflect ) ]
0 commit comments