From 0265436fffb19dbb307a7878f6a1a8da791fec09 Mon Sep 17 00:00:00 2001 From: Gino Valente <49806985+MrGVSV@users.noreply.github.com> Date: Tue, 26 Mar 2024 12:58:29 -0700 Subject: [PATCH] bevy_reflect: Rename `UntypedReflectDeserializer` to `ReflectDeserializer` (#12721) # Objective We have `ReflectSerializer` and `TypedReflectSerializer`. The former is the one users will most often use since the latter takes a bit more effort to deserialize. However, our deserializers are named `UntypedReflectDeserializer` and `TypedReflectDeserializer`. There is no obvious indication that `UntypedReflectDeserializer` must be used with `ReflectSerializer` since the names don't quite match up. ## Solution Rename `UntypedReflectDeserializer` back to `ReflectDeserializer` (initially changed as part of #5723). Also update the docs for both deserializers (as they were pretty out of date) and include doc examples. I also updated the docs for the serializers, too, just so that everything is consistent. --- ## Changelog - Renamed `UntypedReflectDeserializer` to `ReflectDeserializer` - Updated docs for `ReflectDeserializer`, `TypedReflectDeserializer`, `ReflectSerializer`, and `TypedReflectSerializer` ## Migration Guide `UntypedReflectDeserializer` has been renamed to `ReflectDeserializer`. Usages will need to be updated accordingly. ```diff - let reflect_deserializer = UntypedReflectDeserializer::new(®istry); + let reflect_deserializer = ReflectDeserializer::new(®istry); ``` --- crates/bevy_reflect/src/lib.rs | 18 +- crates/bevy_reflect/src/serde/de.rs | 287 +++++++++++++++++++-------- crates/bevy_reflect/src/serde/mod.rs | 8 +- crates/bevy_reflect/src/serde/ser.rs | 75 ++++++- crates/bevy_reflect/src/type_path.rs | 2 +- crates/bevy_scene/src/serde.rs | 6 +- examples/reflection/reflection.rs | 4 +- 7 files changed, 291 insertions(+), 109 deletions(-) diff --git a/crates/bevy_reflect/src/lib.rs b/crates/bevy_reflect/src/lib.rs index 6e016603b2955..073fb5000bfee 100644 --- a/crates/bevy_reflect/src/lib.rs +++ b/crates/bevy_reflect/src/lib.rs @@ -334,7 +334,7 @@ //! The way it works is by moving the serialization logic into common serializers and deserializers: //! * [`ReflectSerializer`] //! * [`TypedReflectSerializer`] -//! * [`UntypedReflectDeserializer`] +//! * [`ReflectDeserializer`] //! * [`TypedReflectDeserializer`] //! //! All of these structs require a reference to the [registry] so that [type information] can be retrieved, @@ -347,7 +347,7 @@ //! and the value is the serialized data. //! The `TypedReflectSerializer` will simply output the serialized data. //! -//! The `UntypedReflectDeserializer` can be used to deserialize this map and return a `Box`, +//! The `ReflectDeserializer` can be used to deserialize this map and return a `Box`, //! where the underlying type will be a dynamic type representing some concrete type (except for value types). //! //! Again, it's important to remember that dynamic types may need to be converted to their concrete counterparts @@ -357,7 +357,7 @@ //! ``` //! # use serde::de::DeserializeSeed; //! # use bevy_reflect::{ -//! # serde::{ReflectSerializer, UntypedReflectDeserializer}, +//! # serde::{ReflectSerializer, ReflectDeserializer}, //! # Reflect, FromReflect, TypeRegistry //! # }; //! #[derive(Reflect, PartialEq, Debug)] @@ -378,7 +378,7 @@ //! let serialized_value: String = ron::to_string(&reflect_serializer).unwrap(); //! //! // Deserialize -//! let reflect_deserializer = UntypedReflectDeserializer::new(®istry); +//! let reflect_deserializer = ReflectDeserializer::new(®istry); //! let deserialized_value: Box = reflect_deserializer.deserialize( //! &mut ron::Deserializer::from_str(&serialized_value).unwrap() //! ).unwrap(); @@ -460,7 +460,7 @@ //! [`serde`]: ::serde //! [`ReflectSerializer`]: serde::ReflectSerializer //! [`TypedReflectSerializer`]: serde::TypedReflectSerializer -//! [`UntypedReflectDeserializer`]: serde::UntypedReflectDeserializer +//! [`ReflectDeserializer`]: serde::ReflectDeserializer //! [`TypedReflectDeserializer`]: serde::TypedReflectDeserializer //! [registry]: TypeRegistry //! [type information]: TypeInfo @@ -610,7 +610,7 @@ mod tests { use super::prelude::*; use super::*; use crate as bevy_reflect; - use crate::serde::{ReflectSerializer, UntypedReflectDeserializer}; + use crate::serde::{ReflectDeserializer, ReflectSerializer}; use crate::utility::GenericTypePathCell; #[test] @@ -1223,7 +1223,7 @@ mod tests { let serialized = to_string_pretty(&serializer, PrettyConfig::default()).unwrap(); let mut deserializer = Deserializer::from_str(&serialized).unwrap(); - let reflect_deserializer = UntypedReflectDeserializer::new(®istry); + let reflect_deserializer = ReflectDeserializer::new(®istry); let value = reflect_deserializer.deserialize(&mut deserializer).unwrap(); let dynamic_struct = value.take::().unwrap(); @@ -2383,7 +2383,7 @@ bevy_reflect::tests::Test { registry.register::(); registry.register::(); - let de = UntypedReflectDeserializer::new(®istry); + let de = ReflectDeserializer::new(®istry); let mut deserializer = Deserializer::from_str(data).expect("Failed to acquire deserializer"); @@ -2440,7 +2440,7 @@ bevy_reflect::tests::Test { registry.add_registration(Vec3::get_type_registration()); registry.add_registration(f32::get_type_registration()); - let de = UntypedReflectDeserializer::new(®istry); + let de = ReflectDeserializer::new(®istry); let mut deserializer = Deserializer::from_str(data).expect("Failed to acquire deserializer"); diff --git a/crates/bevy_reflect/src/serde/de.rs b/crates/bevy_reflect/src/serde/de.rs index a121a7831c188..3087298a8d1e8 100644 --- a/crates/bevy_reflect/src/serde/de.rs +++ b/crates/bevy_reflect/src/serde/de.rs @@ -240,51 +240,6 @@ impl<'de> Deserialize<'de> for Ident { } } -/// A general purpose deserializer for reflected types. -/// -/// This will return a [`Box`] containing the deserialized data. -/// For non-value types, this `Box` will contain the dynamic equivalent. For example, a -/// deserialized struct will return a [`DynamicStruct`] and a `Vec` will return a -/// [`DynamicList`]. For value types, this `Box` will contain the actual value. -/// For example, an `f32` will contain the actual `f32` type. -/// -/// This means that converting to any concrete instance will require the use of -/// [`FromReflect`], or downcasting for value types. -/// -/// Because the type isn't known ahead of time, the serialized data must take the form of -/// a map containing the following entries (in order): -/// 1. `type`: The _full_ [type path] -/// 2. `value`: The serialized value of the reflected type -/// -/// If the type is already known and the [`TypeInfo`] for it can be retrieved, -/// [`TypedReflectDeserializer`] may be used instead to avoid requiring these entries. -/// -/// [`Box`]: crate::Reflect -/// [`FromReflect`]: crate::FromReflect -/// [type path]: crate::TypePath::type_path -pub struct UntypedReflectDeserializer<'a> { - registry: &'a TypeRegistry, -} - -impl<'a> UntypedReflectDeserializer<'a> { - pub fn new(registry: &'a TypeRegistry) -> Self { - Self { registry } - } -} - -impl<'a, 'de> DeserializeSeed<'de> for UntypedReflectDeserializer<'a> { - type Value = Box; - - fn deserialize(self, deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - deserializer.deserialize_map(UntypedReflectDeserializerVisitor { - registry: self.registry, - }) - } -} - /// A deserializer for type registrations. /// /// This will return a [`&TypeRegistration`] corresponding to the given type. @@ -333,53 +288,217 @@ impl<'a, 'de> DeserializeSeed<'de> for TypeRegistrationDeserializer<'a> { } } -struct UntypedReflectDeserializerVisitor<'a> { +/// A general purpose deserializer for reflected types. +/// +/// This is the deserializer counterpart to [`ReflectSerializer`]. +/// +/// See [`TypedReflectDeserializer`] for a deserializer that expects a known type. +/// +/// # Input +/// +/// This deserializer expects a map with a single entry, +/// where the key is the _full_ [type path] of the reflected type +/// and the value is the serialized data. +/// +/// # Output +/// +/// This deserializer will return a [`Box`] containing the deserialized data. +/// +/// For value types (i.e. [`ReflectKind::Value`]) or types that register [`ReflectDeserialize`] type data, +/// this `Box` will contain the expected type. +/// For example, deserializing an `i32` will return a `Box` (as a `Box`). +/// +/// Otherwise, this `Box` will contain the dynamic equivalent. +/// For example, a deserialized struct might return a [`Box`] +/// and a deserialized `Vec` might return a [`Box`]. +/// +/// This means that if the actual type is needed, these dynamic representations will need to +/// be converted to the concrete type using [`FromReflect`] or [`ReflectFromReflect`]. +/// +/// # Example +/// +/// ``` +/// # use serde::de::DeserializeSeed; +/// # use bevy_reflect::prelude::*; +/// # use bevy_reflect::{DynamicStruct, TypeRegistry, serde::ReflectDeserializer}; +/// #[derive(Reflect, PartialEq, Debug)] +/// #[type_path = "my_crate"] +/// struct MyStruct { +/// value: i32 +/// } +/// +/// let mut registry = TypeRegistry::default(); +/// registry.register::(); +/// +/// let input = r#"{ +/// "my_crate::MyStruct": ( +/// value: 123 +/// ) +/// }"#; +/// +/// let mut deserializer = ron::Deserializer::from_str(input).unwrap(); +/// let reflect_deserializer = ReflectDeserializer::new(®istry); +/// +/// let output: Box = reflect_deserializer.deserialize(&mut deserializer).unwrap(); +/// +/// // Since `MyStruct` is not a value type and does not register `ReflectDeserialize`, +/// // we know that its deserialized representation will be a `DynamicStruct`. +/// assert!(output.is::()); +/// assert!(output.represents::()); +/// +/// // We can convert back to `MyStruct` using `FromReflect`. +/// let value: MyStruct = ::from_reflect(&*output).unwrap(); +/// assert_eq!(value, MyStruct { value: 123 }); +/// +/// // We can also do this dynamically with `ReflectFromReflect`. +/// let type_id = output.get_represented_type_info().unwrap().type_id(); +/// let reflect_from_reflect = registry.get_type_data::(type_id).unwrap(); +/// let value: Box = reflect_from_reflect.from_reflect(&*output).unwrap(); +/// assert!(value.is::()); +/// assert_eq!(value.take::().unwrap(), MyStruct { value: 123 }); +/// ``` +/// +/// [`ReflectSerializer`]: crate::serde::ReflectSerializer +/// [type path]: crate::TypePath::type_path +/// [`Box`]: crate::Reflect +/// [`ReflectKind::Value`]: crate::ReflectKind::Value +/// [`ReflectDeserialize`]: crate::ReflectDeserialize +/// [`Box`]: crate::DynamicStruct +/// [`Box`]: crate::DynamicList +/// [`FromReflect`]: crate::FromReflect +/// [`ReflectFromReflect`]: crate::ReflectFromReflect +pub struct ReflectDeserializer<'a> { registry: &'a TypeRegistry, } -impl<'a, 'de> Visitor<'de> for UntypedReflectDeserializerVisitor<'a> { - type Value = Box; - - fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { - formatter.write_str("map containing `type` and `value` entries for the reflected value") +impl<'a> ReflectDeserializer<'a> { + pub fn new(registry: &'a TypeRegistry) -> Self { + Self { registry } } +} + +impl<'a, 'de> DeserializeSeed<'de> for ReflectDeserializer<'a> { + type Value = Box; - fn visit_map(self, mut map: A) -> Result + fn deserialize(self, deserializer: D) -> Result where - A: MapAccess<'de>, + D: serde::Deserializer<'de>, { - let registration = map - .next_key_seed(TypeRegistrationDeserializer::new(self.registry))? - .ok_or_else(|| Error::invalid_length(0, &"a single entry"))?; + struct UntypedReflectDeserializerVisitor<'a> { + registry: &'a TypeRegistry, + } - let value = map.next_value_seed(TypedReflectDeserializer { - registration, - registry: self.registry, - })?; + impl<'a, 'de> Visitor<'de> for UntypedReflectDeserializerVisitor<'a> { + type Value = Box; + + fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { + formatter + .write_str("map containing `type` and `value` entries for the reflected value") + } + + fn visit_map(self, mut map: A) -> Result + where + A: MapAccess<'de>, + { + let registration = map + .next_key_seed(TypeRegistrationDeserializer::new(self.registry))? + .ok_or_else(|| Error::invalid_length(0, &"a single entry"))?; + + let value = map.next_value_seed(TypedReflectDeserializer { + registration, + registry: self.registry, + })?; - if map.next_key::()?.is_some() { - return Err(Error::invalid_length(2, &"a single entry")); + if map.next_key::()?.is_some() { + return Err(Error::invalid_length(2, &"a single entry")); + } + + Ok(value) + } } - Ok(value) + deserializer.deserialize_map(UntypedReflectDeserializerVisitor { + registry: self.registry, + }) } } -/// A deserializer for reflected types whose [`TypeInfo`] is known. +/// A deserializer for reflected types whose [`TypeRegistration`] is known. +/// +/// This is the deserializer counterpart to [`TypedReflectSerializer`]. +/// +/// See [`ReflectDeserializer`] for a deserializer that expects an unknown type. +/// +/// # Input +/// +/// Since the type is already known, the input is just the serialized data. +/// +/// # Output +/// +/// This deserializer will return a [`Box`] containing the deserialized data. /// -/// This will return a [`Box`] containing the deserialized data. -/// For non-value types, this `Box` will contain the dynamic equivalent. For example, a -/// deserialized struct will return a [`DynamicStruct`] and a `Vec` will return a -/// [`DynamicList`]. For value types, this `Box` will contain the actual value. -/// For example, an `f32` will contain the actual `f32` type. +/// For value types (i.e. [`ReflectKind::Value`]) or types that register [`ReflectDeserialize`] type data, +/// this `Box` will contain the expected type. +/// For example, deserializing an `i32` will return a `Box` (as a `Box`). /// -/// This means that converting to any concrete instance will require the use of -/// [`FromReflect`], or downcasting for value types. +/// Otherwise, this `Box` will contain the dynamic equivalent. +/// For example, a deserialized struct might return a [`Box`] +/// and a deserialized `Vec` might return a [`Box`]. /// -/// If the type is not known ahead of time, use [`UntypedReflectDeserializer`] instead. +/// This means that if the actual type is needed, these dynamic representations will need to +/// be converted to the concrete type using [`FromReflect`] or [`ReflectFromReflect`]. +/// +/// # Example +/// +/// ``` +/// # use std::any::TypeId; +/// # use serde::de::DeserializeSeed; +/// # use bevy_reflect::prelude::*; +/// # use bevy_reflect::{DynamicStruct, TypeRegistry, serde::TypedReflectDeserializer}; +/// #[derive(Reflect, PartialEq, Debug)] +/// struct MyStruct { +/// value: i32 +/// } +/// +/// let mut registry = TypeRegistry::default(); +/// registry.register::(); +/// +/// let input = r#"( +/// value: 123 +/// )"#; +/// +/// let registration = registry.get(TypeId::of::()).unwrap(); +/// +/// let mut deserializer = ron::Deserializer::from_str(input).unwrap(); +/// let reflect_deserializer = TypedReflectDeserializer::new(registration, ®istry); +/// +/// let output: Box = reflect_deserializer.deserialize(&mut deserializer).unwrap(); +/// +/// // Since `MyStruct` is not a value type and does not register `ReflectDeserialize`, +/// // we know that its deserialized representation will be a `DynamicStruct`. +/// assert!(output.is::()); +/// assert!(output.represents::()); +/// +/// // We can convert back to `MyStruct` using `FromReflect`. +/// let value: MyStruct = ::from_reflect(&*output).unwrap(); +/// assert_eq!(value, MyStruct { value: 123 }); +/// +/// // We can also do this dynamically with `ReflectFromReflect`. +/// let type_id = output.get_represented_type_info().unwrap().type_id(); +/// let reflect_from_reflect = registry.get_type_data::(type_id).unwrap(); +/// let value: Box = reflect_from_reflect.from_reflect(&*output).unwrap(); +/// assert!(value.is::()); +/// assert_eq!(value.take::().unwrap(), MyStruct { value: 123 }); +/// ``` /// +/// [`TypedReflectSerializer`]: crate::serde::TypedReflectSerializer /// [`Box`]: crate::Reflect +/// [`ReflectKind::Value`]: crate::ReflectKind::Value +/// [`ReflectDeserialize`]: crate::ReflectDeserialize +/// [`Box`]: crate::DynamicStruct +/// [`Box`]: crate::DynamicList /// [`FromReflect`]: crate::FromReflect +/// [`ReflectFromReflect`]: crate::ReflectFromReflect pub struct TypedReflectDeserializer<'a> { registration: &'a TypeRegistration, registry: &'a TypeRegistry, @@ -1062,7 +1181,7 @@ mod tests { use bevy_utils::HashMap; use crate as bevy_reflect; - use crate::serde::{ReflectSerializer, TypedReflectDeserializer, UntypedReflectDeserializer}; + use crate::serde::{ReflectDeserializer, ReflectSerializer, TypedReflectDeserializer}; use crate::{DynamicEnum, FromReflect, Reflect, ReflectDeserialize, TypeRegistry}; #[derive(Reflect, Debug, PartialEq)] @@ -1252,7 +1371,7 @@ mod tests { ), }"#; - let reflect_deserializer = UntypedReflectDeserializer::new(®istry); + let reflect_deserializer = ReflectDeserializer::new(®istry); let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap(); let dynamic_output = reflect_deserializer .deserialize(&mut ron_deserializer) @@ -1269,7 +1388,7 @@ mod tests { }"#; let registry = get_registry(); - let reflect_deserializer = UntypedReflectDeserializer::new(®istry); + let reflect_deserializer = ReflectDeserializer::new(®istry); let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap(); let dynamic_output = reflect_deserializer .deserialize(&mut ron_deserializer) @@ -1336,7 +1455,7 @@ mod tests { ), }"#; - let reflect_deserializer = UntypedReflectDeserializer::new(®istry); + let reflect_deserializer = ReflectDeserializer::new(®istry); let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap(); let dynamic_output = reflect_deserializer .deserialize(&mut ron_deserializer) @@ -1358,7 +1477,7 @@ mod tests { ), }"#; - let reflect_deserializer = UntypedReflectDeserializer::new(®istry); + let reflect_deserializer = ReflectDeserializer::new(®istry); let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap(); let dynamic_output = reflect_deserializer .deserialize(&mut ron_deserializer) @@ -1388,7 +1507,7 @@ mod tests { let input = r#"{ "bevy_reflect::serde::de::tests::MyEnum": Unit, }"#; - let reflect_deserializer = UntypedReflectDeserializer::new(®istry); + let reflect_deserializer = ReflectDeserializer::new(®istry); let mut deserializer = ron::de::Deserializer::from_str(input).unwrap(); let output = reflect_deserializer.deserialize(&mut deserializer).unwrap(); @@ -1399,7 +1518,7 @@ mod tests { let input = r#"{ "bevy_reflect::serde::de::tests::MyEnum": NewType(123), }"#; - let reflect_deserializer = UntypedReflectDeserializer::new(®istry); + let reflect_deserializer = ReflectDeserializer::new(®istry); let mut deserializer = ron::de::Deserializer::from_str(input).unwrap(); let output = reflect_deserializer.deserialize(&mut deserializer).unwrap(); @@ -1410,7 +1529,7 @@ mod tests { let input = r#"{ "bevy_reflect::serde::de::tests::MyEnum": Tuple(1.23, 3.21), }"#; - let reflect_deserializer = UntypedReflectDeserializer::new(®istry); + let reflect_deserializer = ReflectDeserializer::new(®istry); let mut deserializer = ron::de::Deserializer::from_str(input).unwrap(); let output = reflect_deserializer.deserialize(&mut deserializer).unwrap(); @@ -1423,7 +1542,7 @@ mod tests { value: "I <3 Enums", ), }"#; - let reflect_deserializer = UntypedReflectDeserializer::new(®istry); + let reflect_deserializer = ReflectDeserializer::new(®istry); let mut deserializer = ron::de::Deserializer::from_str(input).unwrap(); let output = reflect_deserializer.deserialize(&mut deserializer).unwrap(); @@ -1443,7 +1562,7 @@ mod tests { 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 reflect_deserializer = ReflectDeserializer::new(®istry); let input2 = reflect_deserializer.deserialize(&mut deserializer).unwrap(); let serializer2 = ReflectSerializer::new(&*input2, ®istry); @@ -1473,7 +1592,7 @@ mod tests { 0, ]; - let deserializer = UntypedReflectDeserializer::new(®istry); + let deserializer = ReflectDeserializer::new(®istry); let dynamic_output = bincode::DefaultOptions::new() .with_fixint_encoding() @@ -1505,7 +1624,7 @@ mod tests { let mut reader = std::io::BufReader::new(input.as_slice()); - let deserializer = UntypedReflectDeserializer::new(®istry); + let deserializer = ReflectDeserializer::new(®istry); let dynamic_output = deserializer .deserialize(&mut rmp_serde::Deserializer::new(&mut reader)) .unwrap(); diff --git a/crates/bevy_reflect/src/serde/mod.rs b/crates/bevy_reflect/src/serde/mod.rs index c444279fa928a..0f9833c57efe4 100644 --- a/crates/bevy_reflect/src/serde/mod.rs +++ b/crates/bevy_reflect/src/serde/mod.rs @@ -10,7 +10,7 @@ pub use type_data::*; mod tests { use crate::{self as bevy_reflect, DynamicTupleStruct, Struct}; use crate::{ - serde::{ReflectSerializer, UntypedReflectDeserializer}, + serde::{ReflectDeserializer, ReflectSerializer}, type_registry::TypeRegistry, DynamicStruct, FromReflect, Reflect, }; @@ -52,7 +52,7 @@ mod tests { ron::ser::to_string_pretty(&serializer, ron::ser::PrettyConfig::default()).unwrap(); let mut deserializer = ron::de::Deserializer::from_str(&serialized).unwrap(); - let reflect_deserializer = UntypedReflectDeserializer::new(®istry); + let reflect_deserializer = ReflectDeserializer::new(®istry); let value = reflect_deserializer.deserialize(&mut deserializer).unwrap(); let deserialized = value.take::().unwrap(); @@ -111,7 +111,7 @@ mod tests { ron::ser::to_string_pretty(&serializer, ron::ser::PrettyConfig::default()).unwrap(); let mut deserializer = ron::de::Deserializer::from_str(&serialized).unwrap(); - let reflect_deserializer = UntypedReflectDeserializer::new(®istry); + let reflect_deserializer = ReflectDeserializer::new(®istry); let value = reflect_deserializer.deserialize(&mut deserializer).unwrap(); let deserialized = value.take::().unwrap(); @@ -170,7 +170,7 @@ mod tests { assert_eq!(expected, result); let mut deserializer = ron::de::Deserializer::from_str(&result).unwrap(); - let reflect_deserializer = UntypedReflectDeserializer::new(®istry); + let reflect_deserializer = ReflectDeserializer::new(®istry); let expected = value.clone_value(); let result = reflect_deserializer diff --git a/crates/bevy_reflect/src/serde/ser.rs b/crates/bevy_reflect/src/serde/ser.rs index c67b81e8cc2e2..08e124945cbb6 100644 --- a/crates/bevy_reflect/src/serde/ser.rs +++ b/crates/bevy_reflect/src/serde/ser.rs @@ -52,10 +52,39 @@ fn get_serializable<'a, E: Error>( /// A general purpose serializer for reflected types. /// -/// The serialized data will take the form of a map containing the following entries: -/// 1. `type`: The _full_ [type path] -/// 2. `value`: The serialized value of the reflected type +/// This is the serializer counterpart to [`ReflectDeserializer`]. /// +/// See [`TypedReflectSerializer`] for a serializer that serializes a known type. +/// +/// # Output +/// +/// This serializer will output a map with a single entry, +/// where the key is the _full_ [type path] of the reflected type +/// and the value is the serialized data. +/// +/// # Example +/// +/// ``` +/// # use bevy_reflect::prelude::*; +/// # use bevy_reflect::{TypeRegistry, serde::ReflectSerializer}; +/// #[derive(Reflect, PartialEq, Debug)] +/// #[type_path = "my_crate"] +/// struct MyStruct { +/// value: i32 +/// } +/// +/// let mut registry = TypeRegistry::default(); +/// registry.register::(); +/// +/// let input = MyStruct { value: 123 }; +/// +/// let reflect_serializer = ReflectSerializer::new(&input, ®istry); +/// let output = ron::to_string(&reflect_serializer).unwrap(); +/// +/// assert_eq!(output, r#"{"my_crate::MyStruct":(value:123)}"#); +/// ``` +/// +/// [`ReflectDeserializer`]: crate::serde::ReflectDeserializer /// [type path]: crate::TypePath::type_path pub struct ReflectSerializer<'a> { pub value: &'a dyn Reflect, @@ -97,8 +126,44 @@ impl<'a> Serialize for ReflectSerializer<'a> { } } -/// A serializer for reflected types whose type is known and does not require -/// serialization to include other metadata about it. +/// A serializer for reflected types whose type will be known during deserialization. +/// +/// This is the serializer counterpart to [`TypedReflectDeserializer`]. +/// +/// See [`ReflectSerializer`] for a serializer that serializes an unknown type. +/// +/// # Output +/// +/// Since the type is expected to be known during deserialization, +/// this serializer will not output any additional type information, +/// such as the [type path]. +/// +/// Instead, it will output just the serialized data. +/// +/// # Example +/// +/// ``` +/// # use bevy_reflect::prelude::*; +/// # use bevy_reflect::{TypeRegistry, serde::TypedReflectSerializer}; +/// #[derive(Reflect, PartialEq, Debug)] +/// #[type_path = "my_crate"] +/// struct MyStruct { +/// value: i32 +/// } +/// +/// let mut registry = TypeRegistry::default(); +/// registry.register::(); +/// +/// let input = MyStruct { value: 123 }; +/// +/// let reflect_serializer = TypedReflectSerializer::new(&input, ®istry); +/// let output = ron::to_string(&reflect_serializer).unwrap(); +/// +/// assert_eq!(output, r#"(value:123)"#); +/// ``` +/// +/// [`TypedReflectDeserializer`]: crate::serde::TypedReflectDeserializer +/// [type path]: crate::TypePath::type_path pub struct TypedReflectSerializer<'a> { pub value: &'a dyn Reflect, pub registry: &'a TypeRegistry, diff --git a/crates/bevy_reflect/src/type_path.rs b/crates/bevy_reflect/src/type_path.rs index d48e620d68cd5..9d446cc81088e 100644 --- a/crates/bevy_reflect/src/type_path.rs +++ b/crates/bevy_reflect/src/type_path.rs @@ -72,7 +72,7 @@ use std::fmt; /// ``` /// /// [utility]: crate::utility -/// [(de)serialization]: crate::serde::UntypedReflectDeserializer +/// [(de)serialization]: crate::serde::ReflectDeserializer /// [`Reflect`]: crate::Reflect /// [`type_path`]: TypePath::type_path /// [`short_type_path`]: TypePath::short_type_path diff --git a/crates/bevy_scene/src/serde.rs b/crates/bevy_scene/src/serde.rs index 0904502f2d4e4..54b5f98101635 100644 --- a/crates/bevy_scene/src/serde.rs +++ b/crates/bevy_scene/src/serde.rs @@ -4,7 +4,7 @@ use crate::{DynamicEntity, DynamicScene}; use bevy_ecs::entity::Entity; use bevy_reflect::serde::{TypedReflectDeserializer, TypedReflectSerializer}; use bevy_reflect::{ - serde::{TypeRegistrationDeserializer, UntypedReflectDeserializer}, + serde::{ReflectDeserializer, TypeRegistrationDeserializer}, Reflect, TypeRegistry, TypeRegistryArc, }; use bevy_utils::HashSet; @@ -460,9 +460,7 @@ impl<'a, 'de> Visitor<'de> for SceneMapVisitor<'a> { A: SeqAccess<'de>, { let mut dynamic_properties = Vec::new(); - while let Some(entity) = - seq.next_element_seed(UntypedReflectDeserializer::new(self.registry))? - { + while let Some(entity) = seq.next_element_seed(ReflectDeserializer::new(self.registry))? { dynamic_properties.push(entity); } diff --git a/examples/reflection/reflection.rs b/examples/reflection/reflection.rs index eef610e966f0f..03944b7dc9ad6 100644 --- a/examples/reflection/reflection.rs +++ b/examples/reflection/reflection.rs @@ -7,7 +7,7 @@ use bevy::{ prelude::*, reflect::{ - serde::{ReflectSerializer, UntypedReflectDeserializer}, + serde::{ReflectDeserializer, ReflectSerializer}, DynamicStruct, }, }; @@ -90,7 +90,7 @@ fn setup(type_registry: Res) { info!("{}\n", ron_string); // Dynamic properties can be deserialized - let reflect_deserializer = UntypedReflectDeserializer::new(&type_registry); + let reflect_deserializer = ReflectDeserializer::new(&type_registry); let mut deserializer = ron::de::Deserializer::from_str(&ron_string).unwrap(); let reflect_value = reflect_deserializer.deserialize(&mut deserializer).unwrap();