mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 12:43:34 +00:00
bevy_reflect: Fix dynamic type serialization (#10103)
# Objective Fixes #10086 ## Solution Instead of serializing via `DynamicTypePath::reflect_type_path`, now uses the `TypePath` found on the `TypeInfo` returned by `Reflect::get_represented_type_info`. This issue was happening because the dynamic types implement `TypePath` themselves and do not (and cannot) forward their proxy's `TypePath` data. The solution was to access the proxy's type information in order to get the correct `TypePath` data. ## Changed - The `Debug` impl for `TypePathTable` now includes output for all fields.
This commit is contained in:
parent
71329fe0c2
commit
01b910a148
3 changed files with 57 additions and 4 deletions
|
@ -8,7 +8,7 @@ pub use type_data::*;
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{self as bevy_reflect, DynamicTupleStruct};
|
||||
use crate::{self as bevy_reflect, DynamicTupleStruct, Struct};
|
||||
use crate::{
|
||||
serde::{ReflectSerializer, UntypedReflectDeserializer},
|
||||
type_registry::TypeRegistry,
|
||||
|
@ -94,8 +94,10 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "cannot get type info for bevy_reflect::DynamicStruct")]
|
||||
fn unproxied_dynamic_should_not_serialize() {
|
||||
#[should_panic(
|
||||
expected = "cannot serialize dynamic value without represented type: bevy_reflect::DynamicStruct"
|
||||
)]
|
||||
fn should_not_serialize_unproxied_dynamic() {
|
||||
let registry = TypeRegistry::default();
|
||||
|
||||
let mut value = DynamicStruct::default();
|
||||
|
@ -104,4 +106,36 @@ mod tests {
|
|||
let serializer = ReflectSerializer::new(&value, ®istry);
|
||||
ron::ser::to_string(&serializer).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_roundtrip_proxied_dynamic() {
|
||||
#[derive(Reflect)]
|
||||
struct TestStruct {
|
||||
a: i32,
|
||||
b: i32,
|
||||
}
|
||||
|
||||
let mut registry = TypeRegistry::default();
|
||||
registry.register::<TestStruct>();
|
||||
|
||||
let value: DynamicStruct = TestStruct { a: 123, b: 456 }.clone_dynamic();
|
||||
|
||||
let serializer = ReflectSerializer::new(&value, ®istry);
|
||||
|
||||
let expected = r#"{"bevy_reflect::serde::tests::TestStruct":(a:123,b:456)}"#;
|
||||
let result = ron::ser::to_string(&serializer).unwrap();
|
||||
assert_eq!(expected, result);
|
||||
|
||||
let mut deserializer = ron::de::Deserializer::from_str(&result).unwrap();
|
||||
let reflect_deserializer = UntypedReflectDeserializer::new(®istry);
|
||||
|
||||
let expected = value.clone_value();
|
||||
let result = reflect_deserializer
|
||||
.deserialize(&mut deserializer)
|
||||
.unwrap()
|
||||
.take::<DynamicStruct>()
|
||||
.unwrap();
|
||||
|
||||
assert!(expected.reflect_partial_eq(&result).unwrap());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,7 +68,22 @@ impl<'a> Serialize for ReflectSerializer<'a> {
|
|||
{
|
||||
let mut state = serializer.serialize_map(Some(1))?;
|
||||
state.serialize_entry(
|
||||
self.value.reflect_type_path(),
|
||||
self.value
|
||||
.get_represented_type_info()
|
||||
.ok_or_else(|| {
|
||||
if self.value.is_dynamic() {
|
||||
Error::custom(format_args!(
|
||||
"cannot serialize dynamic value without represented type: {}",
|
||||
self.value.reflect_type_path()
|
||||
))
|
||||
} else {
|
||||
Error::custom(format_args!(
|
||||
"cannot get type info for {}",
|
||||
self.value.reflect_type_path()
|
||||
))
|
||||
}
|
||||
})?
|
||||
.type_path(),
|
||||
&TypedReflectSerializer::new(self.value, self.registry),
|
||||
)?;
|
||||
state.end()
|
||||
|
|
|
@ -183,6 +183,10 @@ impl fmt::Debug for TypePathTable {
|
|||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("TypePathVtable")
|
||||
.field("type_path", &self.type_path)
|
||||
.field("short_type_path", &(self.short_type_path)())
|
||||
.field("type_ident", &(self.type_ident)())
|
||||
.field("crate_name", &(self.crate_name)())
|
||||
.field("module_path", &(self.module_path)())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue