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); ```
This commit is contained in:
parent
e6b5f0574e
commit
0265436fff
@ -334,7 +334,7 @@
|
|||||||
//! The way it works is by moving the serialization logic into common serializers and deserializers:
|
//! The way it works is by moving the serialization logic into common serializers and deserializers:
|
||||||
//! * [`ReflectSerializer`]
|
//! * [`ReflectSerializer`]
|
||||||
//! * [`TypedReflectSerializer`]
|
//! * [`TypedReflectSerializer`]
|
||||||
//! * [`UntypedReflectDeserializer`]
|
//! * [`ReflectDeserializer`]
|
||||||
//! * [`TypedReflectDeserializer`]
|
//! * [`TypedReflectDeserializer`]
|
||||||
//!
|
//!
|
||||||
//! All of these structs require a reference to the [registry] so that [type information] can be retrieved,
|
//! 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.
|
//! and the value is the serialized data.
|
||||||
//! The `TypedReflectSerializer` will simply output the serialized data.
|
//! The `TypedReflectSerializer` will simply output the serialized data.
|
||||||
//!
|
//!
|
||||||
//! The `UntypedReflectDeserializer` can be used to deserialize this map and return a `Box<dyn Reflect>`,
|
//! The `ReflectDeserializer` can be used to deserialize this map and return a `Box<dyn Reflect>`,
|
||||||
//! where the underlying type will be a dynamic type representing some concrete type (except for value types).
|
//! 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
|
//! 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 serde::de::DeserializeSeed;
|
||||||
//! # use bevy_reflect::{
|
//! # use bevy_reflect::{
|
||||||
//! # serde::{ReflectSerializer, UntypedReflectDeserializer},
|
//! # serde::{ReflectSerializer, ReflectDeserializer},
|
||||||
//! # Reflect, FromReflect, TypeRegistry
|
//! # Reflect, FromReflect, TypeRegistry
|
||||||
//! # };
|
//! # };
|
||||||
//! #[derive(Reflect, PartialEq, Debug)]
|
//! #[derive(Reflect, PartialEq, Debug)]
|
||||||
@ -378,7 +378,7 @@
|
|||||||
//! let serialized_value: String = ron::to_string(&reflect_serializer).unwrap();
|
//! let serialized_value: String = ron::to_string(&reflect_serializer).unwrap();
|
||||||
//!
|
//!
|
||||||
//! // Deserialize
|
//! // Deserialize
|
||||||
//! let reflect_deserializer = UntypedReflectDeserializer::new(®istry);
|
//! let reflect_deserializer = ReflectDeserializer::new(®istry);
|
||||||
//! let deserialized_value: Box<dyn Reflect> = reflect_deserializer.deserialize(
|
//! let deserialized_value: Box<dyn Reflect> = reflect_deserializer.deserialize(
|
||||||
//! &mut ron::Deserializer::from_str(&serialized_value).unwrap()
|
//! &mut ron::Deserializer::from_str(&serialized_value).unwrap()
|
||||||
//! ).unwrap();
|
//! ).unwrap();
|
||||||
@ -460,7 +460,7 @@
|
|||||||
//! [`serde`]: ::serde
|
//! [`serde`]: ::serde
|
||||||
//! [`ReflectSerializer`]: serde::ReflectSerializer
|
//! [`ReflectSerializer`]: serde::ReflectSerializer
|
||||||
//! [`TypedReflectSerializer`]: serde::TypedReflectSerializer
|
//! [`TypedReflectSerializer`]: serde::TypedReflectSerializer
|
||||||
//! [`UntypedReflectDeserializer`]: serde::UntypedReflectDeserializer
|
//! [`ReflectDeserializer`]: serde::ReflectDeserializer
|
||||||
//! [`TypedReflectDeserializer`]: serde::TypedReflectDeserializer
|
//! [`TypedReflectDeserializer`]: serde::TypedReflectDeserializer
|
||||||
//! [registry]: TypeRegistry
|
//! [registry]: TypeRegistry
|
||||||
//! [type information]: TypeInfo
|
//! [type information]: TypeInfo
|
||||||
@ -610,7 +610,7 @@ mod tests {
|
|||||||
use super::prelude::*;
|
use super::prelude::*;
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate as bevy_reflect;
|
use crate as bevy_reflect;
|
||||||
use crate::serde::{ReflectSerializer, UntypedReflectDeserializer};
|
use crate::serde::{ReflectDeserializer, ReflectSerializer};
|
||||||
use crate::utility::GenericTypePathCell;
|
use crate::utility::GenericTypePathCell;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1223,7 +1223,7 @@ mod tests {
|
|||||||
let serialized = to_string_pretty(&serializer, PrettyConfig::default()).unwrap();
|
let serialized = to_string_pretty(&serializer, PrettyConfig::default()).unwrap();
|
||||||
|
|
||||||
let mut deserializer = Deserializer::from_str(&serialized).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 value = reflect_deserializer.deserialize(&mut deserializer).unwrap();
|
||||||
let dynamic_struct = value.take::<DynamicStruct>().unwrap();
|
let dynamic_struct = value.take::<DynamicStruct>().unwrap();
|
||||||
|
|
||||||
@ -2383,7 +2383,7 @@ bevy_reflect::tests::Test {
|
|||||||
registry.register::<Quat>();
|
registry.register::<Quat>();
|
||||||
registry.register::<f32>();
|
registry.register::<f32>();
|
||||||
|
|
||||||
let de = UntypedReflectDeserializer::new(®istry);
|
let de = ReflectDeserializer::new(®istry);
|
||||||
|
|
||||||
let mut deserializer =
|
let mut deserializer =
|
||||||
Deserializer::from_str(data).expect("Failed to acquire 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(Vec3::get_type_registration());
|
||||||
registry.add_registration(f32::get_type_registration());
|
registry.add_registration(f32::get_type_registration());
|
||||||
|
|
||||||
let de = UntypedReflectDeserializer::new(®istry);
|
let de = ReflectDeserializer::new(®istry);
|
||||||
|
|
||||||
let mut deserializer =
|
let mut deserializer =
|
||||||
Deserializer::from_str(data).expect("Failed to acquire deserializer");
|
Deserializer::from_str(data).expect("Failed to acquire deserializer");
|
||||||
|
|||||||
@ -240,51 +240,6 @@ impl<'de> Deserialize<'de> for Ident {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A general purpose deserializer for reflected types.
|
|
||||||
///
|
|
||||||
/// This will return a [`Box<dyn Reflect>`] 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<dyn Reflect>`]: 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<dyn Reflect>;
|
|
||||||
|
|
||||||
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
|
|
||||||
where
|
|
||||||
D: serde::Deserializer<'de>,
|
|
||||||
{
|
|
||||||
deserializer.deserialize_map(UntypedReflectDeserializerVisitor {
|
|
||||||
registry: self.registry,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A deserializer for type registrations.
|
/// A deserializer for type registrations.
|
||||||
///
|
///
|
||||||
/// This will return a [`&TypeRegistration`] corresponding to the given type.
|
/// 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<dyn Reflect>`] 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<i32>` (as a `Box<dyn Reflect>`).
|
||||||
|
///
|
||||||
|
/// Otherwise, this `Box` will contain the dynamic equivalent.
|
||||||
|
/// For example, a deserialized struct might return a [`Box<DynamicStruct>`]
|
||||||
|
/// and a deserialized `Vec` might return a [`Box<DynamicList>`].
|
||||||
|
///
|
||||||
|
/// 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::<MyStruct>();
|
||||||
|
///
|
||||||
|
/// 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<dyn Reflect> = 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::<DynamicStruct>());
|
||||||
|
/// assert!(output.represents::<MyStruct>());
|
||||||
|
///
|
||||||
|
/// // We can convert back to `MyStruct` using `FromReflect`.
|
||||||
|
/// let value: MyStruct = <MyStruct as FromReflect>::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::<ReflectFromReflect>(type_id).unwrap();
|
||||||
|
/// let value: Box<dyn Reflect> = reflect_from_reflect.from_reflect(&*output).unwrap();
|
||||||
|
/// assert!(value.is::<MyStruct>());
|
||||||
|
/// assert_eq!(value.take::<MyStruct>().unwrap(), MyStruct { value: 123 });
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// [`ReflectSerializer`]: crate::serde::ReflectSerializer
|
||||||
|
/// [type path]: crate::TypePath::type_path
|
||||||
|
/// [`Box<dyn Reflect>`]: crate::Reflect
|
||||||
|
/// [`ReflectKind::Value`]: crate::ReflectKind::Value
|
||||||
|
/// [`ReflectDeserialize`]: crate::ReflectDeserialize
|
||||||
|
/// [`Box<DynamicStruct>`]: crate::DynamicStruct
|
||||||
|
/// [`Box<DynamicList>`]: crate::DynamicList
|
||||||
|
/// [`FromReflect`]: crate::FromReflect
|
||||||
|
/// [`ReflectFromReflect`]: crate::ReflectFromReflect
|
||||||
|
pub struct ReflectDeserializer<'a> {
|
||||||
registry: &'a TypeRegistry,
|
registry: &'a TypeRegistry,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'de> Visitor<'de> for UntypedReflectDeserializerVisitor<'a> {
|
impl<'a> ReflectDeserializer<'a> {
|
||||||
type Value = Box<dyn Reflect>;
|
pub fn new(registry: &'a TypeRegistry) -> Self {
|
||||||
|
Self { registry }
|
||||||
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
|
|
||||||
formatter.write_str("map containing `type` and `value` entries for the reflected value")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
|
|
||||||
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::<IgnoredAny>()?.is_some() {
|
|
||||||
return Err(Error::invalid_length(2, &"a single entry"));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(value)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A deserializer for reflected types whose [`TypeInfo`] is known.
|
impl<'a, 'de> DeserializeSeed<'de> for ReflectDeserializer<'a> {
|
||||||
|
type Value = Box<dyn Reflect>;
|
||||||
|
|
||||||
|
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
struct UntypedReflectDeserializerVisitor<'a> {
|
||||||
|
registry: &'a TypeRegistry,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'de> Visitor<'de> for UntypedReflectDeserializerVisitor<'a> {
|
||||||
|
type Value = Box<dyn Reflect>;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
|
||||||
|
formatter
|
||||||
|
.write_str("map containing `type` and `value` entries for the reflected value")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
|
||||||
|
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::<IgnoredAny>()?.is_some() {
|
||||||
|
return Err(Error::invalid_length(2, &"a single entry"));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deserializer.deserialize_map(UntypedReflectDeserializerVisitor {
|
||||||
|
registry: self.registry,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A deserializer for reflected types whose [`TypeRegistration`] is known.
|
||||||
///
|
///
|
||||||
/// This will return a [`Box<dyn Reflect>`] containing the deserialized data.
|
/// This is the deserializer counterpart to [`TypedReflectSerializer`].
|
||||||
/// 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
|
/// See [`ReflectDeserializer`] for a deserializer that expects an unknown type.
|
||||||
/// [`FromReflect`], or downcasting for value types.
|
|
||||||
///
|
///
|
||||||
/// If the type is not known ahead of time, use [`UntypedReflectDeserializer`] instead.
|
/// # Input
|
||||||
///
|
///
|
||||||
|
/// Since the type is already known, the input is just the serialized data.
|
||||||
|
///
|
||||||
|
/// # Output
|
||||||
|
///
|
||||||
|
/// This deserializer will return a [`Box<dyn Reflect>`] 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<i32>` (as a `Box<dyn Reflect>`).
|
||||||
|
///
|
||||||
|
/// Otherwise, this `Box` will contain the dynamic equivalent.
|
||||||
|
/// For example, a deserialized struct might return a [`Box<DynamicStruct>`]
|
||||||
|
/// and a deserialized `Vec` might return a [`Box<DynamicList>`].
|
||||||
|
///
|
||||||
|
/// 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::<MyStruct>();
|
||||||
|
///
|
||||||
|
/// let input = r#"(
|
||||||
|
/// value: 123
|
||||||
|
/// )"#;
|
||||||
|
///
|
||||||
|
/// let registration = registry.get(TypeId::of::<MyStruct>()).unwrap();
|
||||||
|
///
|
||||||
|
/// let mut deserializer = ron::Deserializer::from_str(input).unwrap();
|
||||||
|
/// let reflect_deserializer = TypedReflectDeserializer::new(registration, ®istry);
|
||||||
|
///
|
||||||
|
/// let output: Box<dyn Reflect> = 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::<DynamicStruct>());
|
||||||
|
/// assert!(output.represents::<MyStruct>());
|
||||||
|
///
|
||||||
|
/// // We can convert back to `MyStruct` using `FromReflect`.
|
||||||
|
/// let value: MyStruct = <MyStruct as FromReflect>::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::<ReflectFromReflect>(type_id).unwrap();
|
||||||
|
/// let value: Box<dyn Reflect> = reflect_from_reflect.from_reflect(&*output).unwrap();
|
||||||
|
/// assert!(value.is::<MyStruct>());
|
||||||
|
/// assert_eq!(value.take::<MyStruct>().unwrap(), MyStruct { value: 123 });
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// [`TypedReflectSerializer`]: crate::serde::TypedReflectSerializer
|
||||||
/// [`Box<dyn Reflect>`]: crate::Reflect
|
/// [`Box<dyn Reflect>`]: crate::Reflect
|
||||||
|
/// [`ReflectKind::Value`]: crate::ReflectKind::Value
|
||||||
|
/// [`ReflectDeserialize`]: crate::ReflectDeserialize
|
||||||
|
/// [`Box<DynamicStruct>`]: crate::DynamicStruct
|
||||||
|
/// [`Box<DynamicList>`]: crate::DynamicList
|
||||||
/// [`FromReflect`]: crate::FromReflect
|
/// [`FromReflect`]: crate::FromReflect
|
||||||
|
/// [`ReflectFromReflect`]: crate::ReflectFromReflect
|
||||||
pub struct TypedReflectDeserializer<'a> {
|
pub struct TypedReflectDeserializer<'a> {
|
||||||
registration: &'a TypeRegistration,
|
registration: &'a TypeRegistration,
|
||||||
registry: &'a TypeRegistry,
|
registry: &'a TypeRegistry,
|
||||||
@ -1062,7 +1181,7 @@ mod tests {
|
|||||||
use bevy_utils::HashMap;
|
use bevy_utils::HashMap;
|
||||||
|
|
||||||
use crate as bevy_reflect;
|
use crate as bevy_reflect;
|
||||||
use crate::serde::{ReflectSerializer, TypedReflectDeserializer, UntypedReflectDeserializer};
|
use crate::serde::{ReflectDeserializer, ReflectSerializer, TypedReflectDeserializer};
|
||||||
use crate::{DynamicEnum, FromReflect, Reflect, ReflectDeserialize, TypeRegistry};
|
use crate::{DynamicEnum, FromReflect, Reflect, ReflectDeserialize, TypeRegistry};
|
||||||
|
|
||||||
#[derive(Reflect, Debug, PartialEq)]
|
#[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 mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap();
|
||||||
let dynamic_output = reflect_deserializer
|
let dynamic_output = reflect_deserializer
|
||||||
.deserialize(&mut ron_deserializer)
|
.deserialize(&mut ron_deserializer)
|
||||||
@ -1269,7 +1388,7 @@ mod tests {
|
|||||||
}"#;
|
}"#;
|
||||||
|
|
||||||
let registry = get_registry();
|
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 mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap();
|
||||||
let dynamic_output = reflect_deserializer
|
let dynamic_output = reflect_deserializer
|
||||||
.deserialize(&mut ron_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 mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap();
|
||||||
let dynamic_output = reflect_deserializer
|
let dynamic_output = reflect_deserializer
|
||||||
.deserialize(&mut ron_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 mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap();
|
||||||
let dynamic_output = reflect_deserializer
|
let dynamic_output = reflect_deserializer
|
||||||
.deserialize(&mut ron_deserializer)
|
.deserialize(&mut ron_deserializer)
|
||||||
@ -1388,7 +1507,7 @@ mod tests {
|
|||||||
let input = r#"{
|
let input = r#"{
|
||||||
"bevy_reflect::serde::de::tests::MyEnum": Unit,
|
"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 mut deserializer = ron::de::Deserializer::from_str(input).unwrap();
|
||||||
let output = reflect_deserializer.deserialize(&mut deserializer).unwrap();
|
let output = reflect_deserializer.deserialize(&mut deserializer).unwrap();
|
||||||
|
|
||||||
@ -1399,7 +1518,7 @@ mod tests {
|
|||||||
let input = r#"{
|
let input = r#"{
|
||||||
"bevy_reflect::serde::de::tests::MyEnum": NewType(123),
|
"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 mut deserializer = ron::de::Deserializer::from_str(input).unwrap();
|
||||||
let output = reflect_deserializer.deserialize(&mut deserializer).unwrap();
|
let output = reflect_deserializer.deserialize(&mut deserializer).unwrap();
|
||||||
|
|
||||||
@ -1410,7 +1529,7 @@ mod tests {
|
|||||||
let input = r#"{
|
let input = r#"{
|
||||||
"bevy_reflect::serde::de::tests::MyEnum": Tuple(1.23, 3.21),
|
"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 mut deserializer = ron::de::Deserializer::from_str(input).unwrap();
|
||||||
let output = reflect_deserializer.deserialize(&mut deserializer).unwrap();
|
let output = reflect_deserializer.deserialize(&mut deserializer).unwrap();
|
||||||
|
|
||||||
@ -1423,7 +1542,7 @@ mod tests {
|
|||||||
value: "I <3 Enums",
|
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 mut deserializer = ron::de::Deserializer::from_str(input).unwrap();
|
||||||
let output = reflect_deserializer.deserialize(&mut deserializer).unwrap();
|
let output = reflect_deserializer.deserialize(&mut deserializer).unwrap();
|
||||||
|
|
||||||
@ -1443,7 +1562,7 @@ mod tests {
|
|||||||
let serialized1 = ron::ser::to_string(&serializer1).unwrap();
|
let serialized1 = ron::ser::to_string(&serializer1).unwrap();
|
||||||
|
|
||||||
let mut deserializer = ron::de::Deserializer::from_str(&serialized1).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 input2 = reflect_deserializer.deserialize(&mut deserializer).unwrap();
|
||||||
|
|
||||||
let serializer2 = ReflectSerializer::new(&*input2, ®istry);
|
let serializer2 = ReflectSerializer::new(&*input2, ®istry);
|
||||||
@ -1473,7 +1592,7 @@ mod tests {
|
|||||||
0,
|
0,
|
||||||
];
|
];
|
||||||
|
|
||||||
let deserializer = UntypedReflectDeserializer::new(®istry);
|
let deserializer = ReflectDeserializer::new(®istry);
|
||||||
|
|
||||||
let dynamic_output = bincode::DefaultOptions::new()
|
let dynamic_output = bincode::DefaultOptions::new()
|
||||||
.with_fixint_encoding()
|
.with_fixint_encoding()
|
||||||
@ -1505,7 +1624,7 @@ mod tests {
|
|||||||
|
|
||||||
let mut reader = std::io::BufReader::new(input.as_slice());
|
let mut reader = std::io::BufReader::new(input.as_slice());
|
||||||
|
|
||||||
let deserializer = UntypedReflectDeserializer::new(®istry);
|
let deserializer = ReflectDeserializer::new(®istry);
|
||||||
let dynamic_output = deserializer
|
let dynamic_output = deserializer
|
||||||
.deserialize(&mut rmp_serde::Deserializer::new(&mut reader))
|
.deserialize(&mut rmp_serde::Deserializer::new(&mut reader))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|||||||
@ -10,7 +10,7 @@ pub use type_data::*;
|
|||||||
mod tests {
|
mod tests {
|
||||||
use crate::{self as bevy_reflect, DynamicTupleStruct, Struct};
|
use crate::{self as bevy_reflect, DynamicTupleStruct, Struct};
|
||||||
use crate::{
|
use crate::{
|
||||||
serde::{ReflectSerializer, UntypedReflectDeserializer},
|
serde::{ReflectDeserializer, ReflectSerializer},
|
||||||
type_registry::TypeRegistry,
|
type_registry::TypeRegistry,
|
||||||
DynamicStruct, FromReflect, Reflect,
|
DynamicStruct, FromReflect, Reflect,
|
||||||
};
|
};
|
||||||
@ -52,7 +52,7 @@ mod tests {
|
|||||||
ron::ser::to_string_pretty(&serializer, ron::ser::PrettyConfig::default()).unwrap();
|
ron::ser::to_string_pretty(&serializer, ron::ser::PrettyConfig::default()).unwrap();
|
||||||
|
|
||||||
let mut deserializer = ron::de::Deserializer::from_str(&serialized).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 value = reflect_deserializer.deserialize(&mut deserializer).unwrap();
|
||||||
let deserialized = value.take::<DynamicStruct>().unwrap();
|
let deserialized = value.take::<DynamicStruct>().unwrap();
|
||||||
|
|
||||||
@ -111,7 +111,7 @@ mod tests {
|
|||||||
ron::ser::to_string_pretty(&serializer, ron::ser::PrettyConfig::default()).unwrap();
|
ron::ser::to_string_pretty(&serializer, ron::ser::PrettyConfig::default()).unwrap();
|
||||||
|
|
||||||
let mut deserializer = ron::de::Deserializer::from_str(&serialized).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 value = reflect_deserializer.deserialize(&mut deserializer).unwrap();
|
||||||
let deserialized = value.take::<DynamicTupleStruct>().unwrap();
|
let deserialized = value.take::<DynamicTupleStruct>().unwrap();
|
||||||
|
|
||||||
@ -170,7 +170,7 @@ mod tests {
|
|||||||
assert_eq!(expected, result);
|
assert_eq!(expected, result);
|
||||||
|
|
||||||
let mut deserializer = ron::de::Deserializer::from_str(&result).unwrap();
|
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 expected = value.clone_value();
|
||||||
let result = reflect_deserializer
|
let result = reflect_deserializer
|
||||||
|
|||||||
@ -52,10 +52,39 @@ fn get_serializable<'a, E: Error>(
|
|||||||
|
|
||||||
/// A general purpose serializer for reflected types.
|
/// A general purpose serializer for reflected types.
|
||||||
///
|
///
|
||||||
/// The serialized data will take the form of a map containing the following entries:
|
/// This is the serializer counterpart to [`ReflectDeserializer`].
|
||||||
/// 1. `type`: The _full_ [type path]
|
|
||||||
/// 2. `value`: The serialized value of the reflected type
|
|
||||||
///
|
///
|
||||||
|
/// 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::<MyStruct>();
|
||||||
|
///
|
||||||
|
/// 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
|
/// [type path]: crate::TypePath::type_path
|
||||||
pub struct ReflectSerializer<'a> {
|
pub struct ReflectSerializer<'a> {
|
||||||
pub value: &'a dyn Reflect,
|
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
|
/// A serializer for reflected types whose type will be known during deserialization.
|
||||||
/// serialization to include other metadata about it.
|
///
|
||||||
|
/// 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::<MyStruct>();
|
||||||
|
///
|
||||||
|
/// 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 struct TypedReflectSerializer<'a> {
|
||||||
pub value: &'a dyn Reflect,
|
pub value: &'a dyn Reflect,
|
||||||
pub registry: &'a TypeRegistry,
|
pub registry: &'a TypeRegistry,
|
||||||
|
|||||||
@ -72,7 +72,7 @@ use std::fmt;
|
|||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// [utility]: crate::utility
|
/// [utility]: crate::utility
|
||||||
/// [(de)serialization]: crate::serde::UntypedReflectDeserializer
|
/// [(de)serialization]: crate::serde::ReflectDeserializer
|
||||||
/// [`Reflect`]: crate::Reflect
|
/// [`Reflect`]: crate::Reflect
|
||||||
/// [`type_path`]: TypePath::type_path
|
/// [`type_path`]: TypePath::type_path
|
||||||
/// [`short_type_path`]: TypePath::short_type_path
|
/// [`short_type_path`]: TypePath::short_type_path
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use crate::{DynamicEntity, DynamicScene};
|
|||||||
use bevy_ecs::entity::Entity;
|
use bevy_ecs::entity::Entity;
|
||||||
use bevy_reflect::serde::{TypedReflectDeserializer, TypedReflectSerializer};
|
use bevy_reflect::serde::{TypedReflectDeserializer, TypedReflectSerializer};
|
||||||
use bevy_reflect::{
|
use bevy_reflect::{
|
||||||
serde::{TypeRegistrationDeserializer, UntypedReflectDeserializer},
|
serde::{ReflectDeserializer, TypeRegistrationDeserializer},
|
||||||
Reflect, TypeRegistry, TypeRegistryArc,
|
Reflect, TypeRegistry, TypeRegistryArc,
|
||||||
};
|
};
|
||||||
use bevy_utils::HashSet;
|
use bevy_utils::HashSet;
|
||||||
@ -460,9 +460,7 @@ impl<'a, 'de> Visitor<'de> for SceneMapVisitor<'a> {
|
|||||||
A: SeqAccess<'de>,
|
A: SeqAccess<'de>,
|
||||||
{
|
{
|
||||||
let mut dynamic_properties = Vec::new();
|
let mut dynamic_properties = Vec::new();
|
||||||
while let Some(entity) =
|
while let Some(entity) = seq.next_element_seed(ReflectDeserializer::new(self.registry))? {
|
||||||
seq.next_element_seed(UntypedReflectDeserializer::new(self.registry))?
|
|
||||||
{
|
|
||||||
dynamic_properties.push(entity);
|
dynamic_properties.push(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
use bevy::{
|
use bevy::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
reflect::{
|
reflect::{
|
||||||
serde::{ReflectSerializer, UntypedReflectDeserializer},
|
serde::{ReflectDeserializer, ReflectSerializer},
|
||||||
DynamicStruct,
|
DynamicStruct,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -90,7 +90,7 @@ fn setup(type_registry: Res<AppTypeRegistry>) {
|
|||||||
info!("{}\n", ron_string);
|
info!("{}\n", ron_string);
|
||||||
|
|
||||||
// Dynamic properties can be deserialized
|
// 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 mut deserializer = ron::de::Deserializer::from_str(&ron_string).unwrap();
|
||||||
let reflect_value = reflect_deserializer.deserialize(&mut deserializer).unwrap();
|
let reflect_value = reflect_deserializer.deserialize(&mut deserializer).unwrap();
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user