Fix: deserialize DynamicEnum
using index (#12464)
# Objective - Addresses #12462 - When we serialize an enum, deserialize it, then reserialize it, the correct variant should be selected. ## Solution - Change `dynamic_enum.set_variant` to `dynamic_enum.set_variant_with_index` in `EnumVisitor`
This commit is contained in:
parent
76f09e5be2
commit
2278c1edbb
@ -805,8 +805,12 @@ impl<'a, 'de> Visitor<'de> for EnumVisitor<'a> {
|
|||||||
)?
|
)?
|
||||||
.into(),
|
.into(),
|
||||||
};
|
};
|
||||||
|
let variant_name = variant_info.name();
|
||||||
dynamic_enum.set_variant(variant_info.name(), value);
|
let variant_index = self
|
||||||
|
.enum_info
|
||||||
|
.index_of(variant_name)
|
||||||
|
.expect("variant should exist");
|
||||||
|
dynamic_enum.set_variant_with_index(variant_index, variant_name, value);
|
||||||
Ok(dynamic_enum)
|
Ok(dynamic_enum)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1110,7 +1114,7 @@ mod tests {
|
|||||||
use bevy_utils::HashMap;
|
use bevy_utils::HashMap;
|
||||||
|
|
||||||
use crate as bevy_reflect;
|
use crate as bevy_reflect;
|
||||||
use crate::serde::{TypedReflectDeserializer, UntypedReflectDeserializer};
|
use crate::serde::{ReflectSerializer, TypedReflectDeserializer, UntypedReflectDeserializer};
|
||||||
use crate::{DynamicEnum, FromReflect, Reflect, ReflectDeserialize, TypeRegistry};
|
use crate::{DynamicEnum, FromReflect, Reflect, ReflectDeserialize, TypeRegistry};
|
||||||
|
|
||||||
#[derive(Reflect, Debug, PartialEq)]
|
#[derive(Reflect, Debug, PartialEq)]
|
||||||
@ -1168,7 +1172,7 @@ mod tests {
|
|||||||
#[reflect(Deserialize)]
|
#[reflect(Deserialize)]
|
||||||
struct CustomDeserialize {
|
struct CustomDeserialize {
|
||||||
value: usize,
|
value: usize,
|
||||||
#[serde(rename = "renamed")]
|
#[serde(alias = "renamed")]
|
||||||
inner_struct: SomeDeserializableStruct,
|
inner_struct: SomeDeserializableStruct,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1218,12 +1222,11 @@ mod tests {
|
|||||||
registry
|
registry
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
fn get_my_struct() -> MyStruct {
|
||||||
fn should_deserialize() {
|
|
||||||
let mut map = HashMap::new();
|
let mut map = HashMap::new();
|
||||||
map.insert(64, 32);
|
map.insert(64, 32);
|
||||||
|
|
||||||
let expected = MyStruct {
|
MyStruct {
|
||||||
primitive_value: 123,
|
primitive_value: 123,
|
||||||
option_value: Some(String::from("Hello world!")),
|
option_value: Some(String::from("Hello world!")),
|
||||||
option_value_complex: Some(SomeStruct { foo: 123 }),
|
option_value_complex: Some(SomeStruct { foo: 123 }),
|
||||||
@ -1250,7 +1253,13 @@ mod tests {
|
|||||||
value: 100,
|
value: 100,
|
||||||
inner_struct: SomeDeserializableStruct { foo: 101 },
|
inner_struct: SomeDeserializableStruct { foo: 101 },
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_deserialize() {
|
||||||
|
let expected = get_my_struct();
|
||||||
|
let registry = get_registry();
|
||||||
|
|
||||||
let input = r#"{
|
let input = r#"{
|
||||||
"bevy_reflect::serde::de::tests::MyStruct": (
|
"bevy_reflect::serde::de::tests::MyStruct": (
|
||||||
@ -1295,7 +1304,6 @@ mod tests {
|
|||||||
),
|
),
|
||||||
}"#;
|
}"#;
|
||||||
|
|
||||||
let registry = get_registry();
|
|
||||||
let reflect_deserializer = UntypedReflectDeserializer::new(®istry);
|
let reflect_deserializer = UntypedReflectDeserializer::new(®istry);
|
||||||
let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap();
|
let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap();
|
||||||
let dynamic_output = reflect_deserializer
|
let dynamic_output = reflect_deserializer
|
||||||
@ -1477,40 +1485,28 @@ mod tests {
|
|||||||
assert!(expected.reflect_partial_eq(output.as_ref()).unwrap());
|
assert!(expected.reflect_partial_eq(output.as_ref()).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Regression test for https://github.com/bevyengine/bevy/issues/12462
|
||||||
|
#[test]
|
||||||
|
fn should_reserialize() {
|
||||||
|
let registry = get_registry();
|
||||||
|
let input1 = get_my_struct();
|
||||||
|
|
||||||
|
let serializer1 = ReflectSerializer::new(&input1, ®istry);
|
||||||
|
let serialized1 = ron::ser::to_string(&serializer1).unwrap();
|
||||||
|
|
||||||
|
let mut deserializer = ron::de::Deserializer::from_str(&serialized1).unwrap();
|
||||||
|
let reflect_deserializer = UntypedReflectDeserializer::new(®istry);
|
||||||
|
let input2 = reflect_deserializer.deserialize(&mut deserializer).unwrap();
|
||||||
|
|
||||||
|
let serializer2 = ReflectSerializer::new(&*input2, ®istry);
|
||||||
|
let serialized2 = ron::ser::to_string(&serializer2).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(serialized1, serialized2);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_deserialize_non_self_describing_binary() {
|
fn should_deserialize_non_self_describing_binary() {
|
||||||
let mut map = HashMap::new();
|
let expected = get_my_struct();
|
||||||
map.insert(64, 32);
|
|
||||||
|
|
||||||
let expected = MyStruct {
|
|
||||||
primitive_value: 123,
|
|
||||||
option_value: Some(String::from("Hello world!")),
|
|
||||||
option_value_complex: Some(SomeStruct { foo: 123 }),
|
|
||||||
tuple_value: (PI, 1337),
|
|
||||||
list_value: vec![-2, -1, 0, 1, 2],
|
|
||||||
array_value: [-2, -1, 0, 1, 2],
|
|
||||||
map_value: map,
|
|
||||||
struct_value: SomeStruct { foo: 999999999 },
|
|
||||||
tuple_struct_value: SomeTupleStruct(String::from("Tuple Struct")),
|
|
||||||
unit_struct: SomeUnitStruct,
|
|
||||||
unit_enum: SomeEnum::Unit,
|
|
||||||
newtype_enum: SomeEnum::NewType(123),
|
|
||||||
tuple_enum: SomeEnum::Tuple(1.23, 3.21),
|
|
||||||
struct_enum: SomeEnum::Struct {
|
|
||||||
foo: String::from("Struct variant value"),
|
|
||||||
},
|
|
||||||
ignored_struct: SomeIgnoredStruct { ignored: 0 },
|
|
||||||
ignored_tuple_struct: SomeIgnoredTupleStruct(0),
|
|
||||||
ignored_struct_variant: SomeIgnoredEnum::Struct {
|
|
||||||
foo: String::default(),
|
|
||||||
},
|
|
||||||
ignored_tuple_variant: SomeIgnoredEnum::Tuple(0.0, 0.0),
|
|
||||||
custom_deserialize: CustomDeserialize {
|
|
||||||
value: 100,
|
|
||||||
inner_struct: SomeDeserializableStruct { foo: 101 },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let registry = get_registry();
|
let registry = get_registry();
|
||||||
|
|
||||||
let input = vec![
|
let input = vec![
|
||||||
@ -1542,38 +1538,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_deserialize_self_describing_binary() {
|
fn should_deserialize_self_describing_binary() {
|
||||||
let mut map = HashMap::new();
|
let expected = get_my_struct();
|
||||||
map.insert(64, 32);
|
|
||||||
|
|
||||||
let expected = MyStruct {
|
|
||||||
primitive_value: 123,
|
|
||||||
option_value: Some(String::from("Hello world!")),
|
|
||||||
option_value_complex: Some(SomeStruct { foo: 123 }),
|
|
||||||
tuple_value: (PI, 1337),
|
|
||||||
list_value: vec![-2, -1, 0, 1, 2],
|
|
||||||
array_value: [-2, -1, 0, 1, 2],
|
|
||||||
map_value: map,
|
|
||||||
struct_value: SomeStruct { foo: 999999999 },
|
|
||||||
tuple_struct_value: SomeTupleStruct(String::from("Tuple Struct")),
|
|
||||||
unit_struct: SomeUnitStruct,
|
|
||||||
unit_enum: SomeEnum::Unit,
|
|
||||||
newtype_enum: SomeEnum::NewType(123),
|
|
||||||
tuple_enum: SomeEnum::Tuple(1.23, 3.21),
|
|
||||||
struct_enum: SomeEnum::Struct {
|
|
||||||
foo: String::from("Struct variant value"),
|
|
||||||
},
|
|
||||||
ignored_struct: SomeIgnoredStruct { ignored: 0 },
|
|
||||||
ignored_tuple_struct: SomeIgnoredTupleStruct(0),
|
|
||||||
ignored_struct_variant: SomeIgnoredEnum::Struct {
|
|
||||||
foo: String::default(),
|
|
||||||
},
|
|
||||||
ignored_tuple_variant: SomeIgnoredEnum::Tuple(0.0, 0.0),
|
|
||||||
custom_deserialize: CustomDeserialize {
|
|
||||||
value: 100,
|
|
||||||
inner_struct: SomeDeserializableStruct { foo: 101 },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let registry = get_registry();
|
let registry = get_registry();
|
||||||
|
|
||||||
let input = vec![
|
let input = vec![
|
||||||
|
@ -574,12 +574,10 @@ mod tests {
|
|||||||
registry
|
registry
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
fn get_my_struct() -> MyStruct {
|
||||||
fn should_serialize() {
|
|
||||||
let mut map = HashMap::new();
|
let mut map = HashMap::new();
|
||||||
map.insert(64, 32);
|
map.insert(64, 32);
|
||||||
|
MyStruct {
|
||||||
let input = MyStruct {
|
|
||||||
primitive_value: 123,
|
primitive_value: 123,
|
||||||
option_value: Some(String::from("Hello world!")),
|
option_value: Some(String::from("Hello world!")),
|
||||||
option_value_complex: Some(SomeStruct { foo: 123 }),
|
option_value_complex: Some(SomeStruct { foo: 123 }),
|
||||||
@ -606,9 +604,14 @@ mod tests {
|
|||||||
value: 100,
|
value: 100,
|
||||||
inner_struct: SomeSerializableStruct { foo: 101 },
|
inner_struct: SomeSerializableStruct { foo: 101 },
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_serialize() {
|
||||||
|
let input = get_my_struct();
|
||||||
let registry = get_registry();
|
let registry = get_registry();
|
||||||
|
|
||||||
let serializer = ReflectSerializer::new(&input, ®istry);
|
let serializer = ReflectSerializer::new(&input, ®istry);
|
||||||
|
|
||||||
let config = PrettyConfig::default()
|
let config = PrettyConfig::default()
|
||||||
@ -776,38 +779,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_serialize_non_self_describing_binary() {
|
fn should_serialize_non_self_describing_binary() {
|
||||||
let mut map = HashMap::new();
|
let input = get_my_struct();
|
||||||
map.insert(64, 32);
|
|
||||||
|
|
||||||
let input = MyStruct {
|
|
||||||
primitive_value: 123,
|
|
||||||
option_value: Some(String::from("Hello world!")),
|
|
||||||
option_value_complex: Some(SomeStruct { foo: 123 }),
|
|
||||||
tuple_value: (PI, 1337),
|
|
||||||
list_value: vec![-2, -1, 0, 1, 2],
|
|
||||||
array_value: [-2, -1, 0, 1, 2],
|
|
||||||
map_value: map,
|
|
||||||
struct_value: SomeStruct { foo: 999999999 },
|
|
||||||
tuple_struct_value: SomeTupleStruct(String::from("Tuple Struct")),
|
|
||||||
unit_struct: SomeUnitStruct,
|
|
||||||
unit_enum: SomeEnum::Unit,
|
|
||||||
newtype_enum: SomeEnum::NewType(123),
|
|
||||||
tuple_enum: SomeEnum::Tuple(1.23, 3.21),
|
|
||||||
struct_enum: SomeEnum::Struct {
|
|
||||||
foo: String::from("Struct variant value"),
|
|
||||||
},
|
|
||||||
ignored_struct: SomeIgnoredStruct { ignored: 123 },
|
|
||||||
ignored_tuple_struct: SomeIgnoredTupleStruct(123),
|
|
||||||
ignored_struct_variant: SomeIgnoredEnum::Struct {
|
|
||||||
foo: String::from("Struct Variant"),
|
|
||||||
},
|
|
||||||
ignored_tuple_variant: SomeIgnoredEnum::Tuple(1.23, 3.45),
|
|
||||||
custom_serialize: CustomSerialize {
|
|
||||||
value: 100,
|
|
||||||
inner_struct: SomeSerializableStruct { foo: 101 },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let registry = get_registry();
|
let registry = get_registry();
|
||||||
|
|
||||||
let serializer = ReflectSerializer::new(&input, ®istry);
|
let serializer = ReflectSerializer::new(&input, ®istry);
|
||||||
@ -834,38 +806,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_serialize_self_describing_binary() {
|
fn should_serialize_self_describing_binary() {
|
||||||
let mut map = HashMap::new();
|
let input = get_my_struct();
|
||||||
map.insert(64, 32);
|
|
||||||
|
|
||||||
let input = MyStruct {
|
|
||||||
primitive_value: 123,
|
|
||||||
option_value: Some(String::from("Hello world!")),
|
|
||||||
option_value_complex: Some(SomeStruct { foo: 123 }),
|
|
||||||
tuple_value: (PI, 1337),
|
|
||||||
list_value: vec![-2, -1, 0, 1, 2],
|
|
||||||
array_value: [-2, -1, 0, 1, 2],
|
|
||||||
map_value: map,
|
|
||||||
struct_value: SomeStruct { foo: 999999999 },
|
|
||||||
tuple_struct_value: SomeTupleStruct(String::from("Tuple Struct")),
|
|
||||||
unit_struct: SomeUnitStruct,
|
|
||||||
unit_enum: SomeEnum::Unit,
|
|
||||||
newtype_enum: SomeEnum::NewType(123),
|
|
||||||
tuple_enum: SomeEnum::Tuple(1.23, 3.21),
|
|
||||||
struct_enum: SomeEnum::Struct {
|
|
||||||
foo: String::from("Struct variant value"),
|
|
||||||
},
|
|
||||||
ignored_struct: SomeIgnoredStruct { ignored: 123 },
|
|
||||||
ignored_tuple_struct: SomeIgnoredTupleStruct(123),
|
|
||||||
ignored_struct_variant: SomeIgnoredEnum::Struct {
|
|
||||||
foo: String::from("Struct Variant"),
|
|
||||||
},
|
|
||||||
ignored_tuple_variant: SomeIgnoredEnum::Tuple(1.23, 3.45),
|
|
||||||
custom_serialize: CustomSerialize {
|
|
||||||
value: 100,
|
|
||||||
inner_struct: SomeSerializableStruct { foo: 101 },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let registry = get_registry();
|
let registry = get_registry();
|
||||||
|
|
||||||
let serializer = ReflectSerializer::new(&input, ®istry);
|
let serializer = ReflectSerializer::new(&input, ®istry);
|
||||||
|
Loading…
Reference in New Issue
Block a user