Vendor dependencies for 0.3.0 release

This commit is contained in:
2025-09-27 10:29:08 -05:00
parent 0c8d39d483
commit 82ab7f317b
26803 changed files with 16134934 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
use crate::{
serde::{de::registration_utils::try_get_registration, TypedReflectDeserializer},
ArrayInfo, DynamicArray, TypeRegistry,
};
use alloc::{string::ToString, vec::Vec};
use core::{fmt, fmt::Formatter};
use serde::de::{Error, SeqAccess, Visitor};
use super::ReflectDeserializerProcessor;
/// A [`Visitor`] for deserializing [`Array`] values.
///
/// [`Array`]: crate::Array
pub(super) struct ArrayVisitor<'a, P> {
pub array_info: &'static ArrayInfo,
pub registry: &'a TypeRegistry,
pub processor: Option<&'a mut P>,
}
impl<'de, P: ReflectDeserializerProcessor> Visitor<'de> for ArrayVisitor<'_, P> {
type Value = DynamicArray;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("reflected array value")
}
fn visit_seq<V>(mut self, mut seq: V) -> Result<Self::Value, V::Error>
where
V: SeqAccess<'de>,
{
let mut vec = Vec::with_capacity(seq.size_hint().unwrap_or_default());
let registration = try_get_registration(self.array_info.item_ty(), self.registry)?;
while let Some(value) = seq.next_element_seed(TypedReflectDeserializer::new_internal(
registration,
self.registry,
self.processor.as_deref_mut(),
))? {
vec.push(value);
}
if vec.len() != self.array_info.capacity() {
return Err(Error::invalid_length(
vec.len(),
&self.array_info.capacity().to_string().as_str(),
));
}
Ok(DynamicArray::new(vec.into_boxed_slice()))
}
}

View File

@@ -0,0 +1,84 @@
use crate::serde::de::error_utils::make_custom_error;
use crate::{FromType, PartialReflect, TypeRegistry};
use alloc::boxed::Box;
use serde::Deserializer;
/// Trait used to provide finer control when deserializing a reflected type with one of
/// the reflection deserializers.
///
/// This trait is the reflection equivalent of `serde`'s [`Deserialize`] trait.
/// The main difference is that this trait provides access to the [`TypeRegistry`],
/// which means that we can use the registry and all its stored type information
/// to deserialize our type.
///
/// This can be useful when writing a custom reflection deserializer where we may
/// want to handle parts of the deserialization process, but temporarily pass control
/// to the standard reflection deserializer for other parts.
///
/// For the serialization equivalent of this trait, see [`SerializeWithRegistry`].
///
/// # Rationale
///
/// Without this trait and its associated [type data], such a deserializer would have to
/// write out all of the deserialization logic itself, possibly including
/// unnecessary code duplication and trivial implementations.
///
/// This is because a normal [`Deserialize`] implementation has no knowledge of the
/// [`TypeRegistry`] and therefore cannot create a reflection-based deserializer for
/// nested items.
///
/// # Implementors
///
/// In order for this to work with the reflection deserializers like [`TypedReflectDeserializer`]
/// and [`ReflectDeserializer`], implementors should be sure to register the
/// [`ReflectDeserializeWithRegistry`] type data.
/// This can be done [via the registry] or by adding `#[reflect(DeserializeWithRegistry)]` to
/// the type definition.
///
/// [`Deserialize`]: ::serde::Deserialize
/// [`SerializeWithRegistry`]: crate::serde::SerializeWithRegistry
/// [type data]: ReflectDeserializeWithRegistry
/// [`TypedReflectDeserializer`]: crate::serde::TypedReflectDeserializer
/// [`ReflectDeserializer`]: crate::serde::ReflectDeserializer
/// [via the registry]: TypeRegistry::register_type_data
pub trait DeserializeWithRegistry<'de>: Sized {
fn deserialize<D>(deserializer: D, registry: &TypeRegistry) -> Result<Self, D::Error>
where
D: Deserializer<'de>;
}
/// Type data used to deserialize a [`PartialReflect`] type with a custom [`DeserializeWithRegistry`] implementation.
#[derive(Clone)]
pub struct ReflectDeserializeWithRegistry {
deserialize: fn(
deserializer: &mut dyn erased_serde::Deserializer,
registry: &TypeRegistry,
) -> Result<Box<dyn PartialReflect>, erased_serde::Error>,
}
impl ReflectDeserializeWithRegistry {
/// Deserialize a [`PartialReflect`] type with this type data's custom [`DeserializeWithRegistry`] implementation.
pub fn deserialize<'de, D>(
&self,
deserializer: D,
registry: &TypeRegistry,
) -> Result<Box<dyn PartialReflect>, D::Error>
where
D: Deserializer<'de>,
{
let mut erased = <dyn erased_serde::Deserializer>::erase(deserializer);
(self.deserialize)(&mut erased, registry).map_err(make_custom_error)
}
}
impl<T: PartialReflect + for<'de> DeserializeWithRegistry<'de>> FromType<T>
for ReflectDeserializeWithRegistry
{
fn from_type() -> Self {
Self {
deserialize: |deserializer, registry| {
Ok(Box::new(T::deserialize(deserializer, registry)?))
},
}
}
}

View File

@@ -0,0 +1,531 @@
#[cfg(feature = "debug_stack")]
use crate::serde::de::error_utils::TYPE_INFO_STACK;
use crate::serde::{ReflectDeserializeWithRegistry, SerializationData};
use crate::{
serde::{
de::{
arrays::ArrayVisitor, enums::EnumVisitor, error_utils::make_custom_error,
lists::ListVisitor, maps::MapVisitor, options::OptionVisitor, sets::SetVisitor,
structs::StructVisitor, tuple_structs::TupleStructVisitor, tuples::TupleVisitor,
},
TypeRegistrationDeserializer,
},
PartialReflect, ReflectDeserialize, TypeInfo, TypePath, TypeRegistration, TypeRegistry,
};
use alloc::boxed::Box;
use core::{fmt, fmt::Formatter};
use serde::de::{DeserializeSeed, Error, IgnoredAny, MapAccess, Visitor};
use super::ReflectDeserializerProcessor;
/// 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 opaque types (i.e. [`ReflectKind::Opaque`]) 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`].
///
/// If you want to override deserialization for a specific [`TypeRegistration`],
/// you can pass in a reference to a [`ReflectDeserializerProcessor`] which will
/// take priority over all other deserialization methods - see [`with_processor`].
///
/// # 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(&registry);
///
/// let output: Box<dyn PartialReflect> = reflect_deserializer.deserialize(&mut deserializer).unwrap();
///
/// // Since `MyStruct` is not an opaque type and does not register `ReflectDeserialize`,
/// // we know that its deserialized value will be a `DynamicStruct`,
/// // although it will represent `MyStruct`.
/// assert!(output.as_partial_reflect().represents::<MyStruct>());
///
/// // We can convert back to `MyStruct` using `FromReflect`.
/// let value: MyStruct = <MyStruct as FromReflect>::from_reflect(output.as_partial_reflect()).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.as_partial_reflect()).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::Opaque`]: crate::ReflectKind::Opaque
/// [`ReflectDeserialize`]: crate::ReflectDeserialize
/// [`Box<DynamicStruct>`]: crate::DynamicStruct
/// [`Box<DynamicList>`]: crate::DynamicList
/// [`FromReflect`]: crate::FromReflect
/// [`ReflectFromReflect`]: crate::ReflectFromReflect
/// [`with_processor`]: Self::with_processor
pub struct ReflectDeserializer<'a, P: ReflectDeserializerProcessor = ()> {
registry: &'a TypeRegistry,
processor: Option<&'a mut P>,
}
impl<'a> ReflectDeserializer<'a, ()> {
/// Creates a deserializer with no processor.
///
/// If you want to add custom logic for deserializing certain types, use
/// [`with_processor`].
///
/// [`with_processor`]: Self::with_processor
pub fn new(registry: &'a TypeRegistry) -> Self {
Self {
registry,
processor: None,
}
}
}
impl<'a, P: ReflectDeserializerProcessor> ReflectDeserializer<'a, P> {
/// Creates a deserializer with a processor.
///
/// If you do not need any custom logic for handling certain types, use
/// [`new`].
///
/// [`new`]: Self::new
pub fn with_processor(registry: &'a TypeRegistry, processor: &'a mut P) -> Self {
Self {
registry,
processor: Some(processor),
}
}
}
impl<'de, P: ReflectDeserializerProcessor> DeserializeSeed<'de> for ReflectDeserializer<'_, P> {
type Value = Box<dyn PartialReflect>;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>,
{
struct UntypedReflectDeserializerVisitor<'a, P> {
registry: &'a TypeRegistry,
processor: Option<&'a mut P>,
}
impl<'de, P: ReflectDeserializerProcessor> Visitor<'de>
for UntypedReflectDeserializerVisitor<'_, P>
{
type Value = Box<dyn PartialReflect>;
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::new_internal(
registration,
self.registry,
self.processor,
))?;
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,
processor: self.processor,
})
}
}
/// 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<dyn Reflect>`] containing the deserialized data.
///
/// For opaque types (i.e. [`ReflectKind::Opaque`]) 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`].
///
/// If you want to override deserialization for a specific [`TypeRegistration`],
/// you can pass in a reference to a [`ReflectDeserializerProcessor`] which will
/// take priority over all other deserialization methods - see [`with_processor`].
///
/// # Example
///
/// ```
/// # use core::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, &registry);
///
/// let output: Box<dyn PartialReflect> = reflect_deserializer.deserialize(&mut deserializer).unwrap();
///
/// // Since `MyStruct` is not an opaque type and does not register `ReflectDeserialize`,
/// // we know that its deserialized value will be a `DynamicStruct`,
/// // although it will represent `MyStruct`.
/// assert!(output.as_partial_reflect().represents::<MyStruct>());
///
/// // We can convert back to `MyStruct` using `FromReflect`.
/// let value: MyStruct = <MyStruct as FromReflect>::from_reflect(output.as_partial_reflect()).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.as_partial_reflect()).unwrap();
/// assert!(value.is::<MyStruct>());
/// assert_eq!(value.take::<MyStruct>().unwrap(), MyStruct { value: 123 });
/// ```
///
/// [`TypedReflectSerializer`]: crate::serde::TypedReflectSerializer
/// [`Box<dyn Reflect>`]: crate::Reflect
/// [`ReflectKind::Opaque`]: crate::ReflectKind::Opaque
/// [`ReflectDeserialize`]: crate::ReflectDeserialize
/// [`Box<DynamicStruct>`]: crate::DynamicStruct
/// [`Box<DynamicList>`]: crate::DynamicList
/// [`FromReflect`]: crate::FromReflect
/// [`ReflectFromReflect`]: crate::ReflectFromReflect
/// [`with_processor`]: Self::with_processor
pub struct TypedReflectDeserializer<'a, P: ReflectDeserializerProcessor = ()> {
registration: &'a TypeRegistration,
registry: &'a TypeRegistry,
processor: Option<&'a mut P>,
}
impl<'a> TypedReflectDeserializer<'a, ()> {
/// Creates a typed deserializer with no processor.
///
/// If you want to add custom logic for deserializing certain types, use
/// [`with_processor`].
///
/// [`with_processor`]: Self::with_processor
pub fn new(registration: &'a TypeRegistration, registry: &'a TypeRegistry) -> Self {
#[cfg(feature = "debug_stack")]
TYPE_INFO_STACK.set(crate::type_info_stack::TypeInfoStack::new());
Self {
registration,
registry,
processor: None,
}
}
/// Creates a new [`TypedReflectDeserializer`] for the given type `T`
/// without a processor.
///
/// # Panics
///
/// Panics if `T` is not registered in the given [`TypeRegistry`].
pub fn of<T: TypePath>(registry: &'a TypeRegistry) -> Self {
let registration = registry
.get(core::any::TypeId::of::<T>())
.unwrap_or_else(|| panic!("no registration found for type `{}`", T::type_path()));
Self {
registration,
registry,
processor: None,
}
}
}
impl<'a, P: ReflectDeserializerProcessor> TypedReflectDeserializer<'a, P> {
/// Creates a typed deserializer with a processor.
///
/// If you do not need any custom logic for handling certain types, use
/// [`new`].
///
/// [`new`]: Self::new
pub fn with_processor(
registration: &'a TypeRegistration,
registry: &'a TypeRegistry,
processor: &'a mut P,
) -> Self {
#[cfg(feature = "debug_stack")]
TYPE_INFO_STACK.set(crate::type_info_stack::TypeInfoStack::new());
Self {
registration,
registry,
processor: Some(processor),
}
}
/// An internal constructor for creating a deserializer without resetting the type info stack.
pub(super) fn new_internal(
registration: &'a TypeRegistration,
registry: &'a TypeRegistry,
processor: Option<&'a mut P>,
) -> Self {
Self {
registration,
registry,
processor,
}
}
}
impl<'de, P: ReflectDeserializerProcessor> DeserializeSeed<'de>
for TypedReflectDeserializer<'_, P>
{
type Value = Box<dyn PartialReflect>;
fn deserialize<D>(mut self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>,
{
let deserialize_internal = || -> Result<Self::Value, D::Error> {
// First, check if our processor wants to deserialize this type
// This takes priority over any other deserialization operations
let deserializer = if let Some(processor) = self.processor.as_deref_mut() {
match processor.try_deserialize(self.registration, self.registry, deserializer) {
Ok(Ok(value)) => {
return Ok(value);
}
Err(err) => {
return Err(make_custom_error(err));
}
Ok(Err(deserializer)) => deserializer,
}
} else {
deserializer
};
let type_path = self.registration.type_info().type_path();
// Handle both Value case and types that have a custom `ReflectDeserialize`
if let Some(deserialize_reflect) = self.registration.data::<ReflectDeserialize>() {
let value = deserialize_reflect.deserialize(deserializer)?;
return Ok(value.into_partial_reflect());
}
if let Some(deserialize_reflect) =
self.registration.data::<ReflectDeserializeWithRegistry>()
{
let value = deserialize_reflect.deserialize(deserializer, self.registry)?;
return Ok(value);
}
match self.registration.type_info() {
TypeInfo::Struct(struct_info) => {
let mut dynamic_struct = deserializer.deserialize_struct(
struct_info.type_path_table().ident().unwrap(),
struct_info.field_names(),
StructVisitor {
struct_info,
registration: self.registration,
registry: self.registry,
processor: self.processor,
},
)?;
dynamic_struct.set_represented_type(Some(self.registration.type_info()));
Ok(Box::new(dynamic_struct))
}
TypeInfo::TupleStruct(tuple_struct_info) => {
let mut dynamic_tuple_struct = if tuple_struct_info.field_len() == 1
&& self.registration.data::<SerializationData>().is_none()
{
deserializer.deserialize_newtype_struct(
tuple_struct_info.type_path_table().ident().unwrap(),
TupleStructVisitor {
tuple_struct_info,
registration: self.registration,
registry: self.registry,
processor: self.processor,
},
)?
} else {
deserializer.deserialize_tuple_struct(
tuple_struct_info.type_path_table().ident().unwrap(),
tuple_struct_info.field_len(),
TupleStructVisitor {
tuple_struct_info,
registration: self.registration,
registry: self.registry,
processor: self.processor,
},
)?
};
dynamic_tuple_struct.set_represented_type(Some(self.registration.type_info()));
Ok(Box::new(dynamic_tuple_struct))
}
TypeInfo::List(list_info) => {
let mut dynamic_list = deserializer.deserialize_seq(ListVisitor {
list_info,
registry: self.registry,
processor: self.processor,
})?;
dynamic_list.set_represented_type(Some(self.registration.type_info()));
Ok(Box::new(dynamic_list))
}
TypeInfo::Array(array_info) => {
let mut dynamic_array = deserializer.deserialize_tuple(
array_info.capacity(),
ArrayVisitor {
array_info,
registry: self.registry,
processor: self.processor,
},
)?;
dynamic_array.set_represented_type(Some(self.registration.type_info()));
Ok(Box::new(dynamic_array))
}
TypeInfo::Map(map_info) => {
let mut dynamic_map = deserializer.deserialize_map(MapVisitor {
map_info,
registry: self.registry,
processor: self.processor,
})?;
dynamic_map.set_represented_type(Some(self.registration.type_info()));
Ok(Box::new(dynamic_map))
}
TypeInfo::Set(set_info) => {
let mut dynamic_set = deserializer.deserialize_seq(SetVisitor {
set_info,
registry: self.registry,
processor: self.processor,
})?;
dynamic_set.set_represented_type(Some(self.registration.type_info()));
Ok(Box::new(dynamic_set))
}
TypeInfo::Tuple(tuple_info) => {
let mut dynamic_tuple = deserializer.deserialize_tuple(
tuple_info.field_len(),
TupleVisitor {
tuple_info,
registration: self.registration,
registry: self.registry,
processor: self.processor,
},
)?;
dynamic_tuple.set_represented_type(Some(self.registration.type_info()));
Ok(Box::new(dynamic_tuple))
}
TypeInfo::Enum(enum_info) => {
let mut dynamic_enum = if enum_info.type_path_table().module_path()
== Some("core::option")
&& enum_info.type_path_table().ident() == Some("Option")
{
deserializer.deserialize_option(OptionVisitor {
enum_info,
registry: self.registry,
processor: self.processor,
})?
} else {
deserializer.deserialize_enum(
enum_info.type_path_table().ident().unwrap(),
enum_info.variant_names(),
EnumVisitor {
enum_info,
registration: self.registration,
registry: self.registry,
processor: self.processor,
},
)?
};
dynamic_enum.set_represented_type(Some(self.registration.type_info()));
Ok(Box::new(dynamic_enum))
}
TypeInfo::Opaque(_) => {
// This case should already be handled
Err(make_custom_error(format_args!(
"type `{type_path}` did not register the `ReflectDeserialize` type data. For certain types, this may need to be registered manually using `register_type_data`",
)))
}
}
};
#[cfg(feature = "debug_stack")]
TYPE_INFO_STACK.with_borrow_mut(|stack| stack.push(self.registration.type_info()));
let output = deserialize_internal();
#[cfg(feature = "debug_stack")]
TYPE_INFO_STACK.with_borrow_mut(crate::type_info_stack::TypeInfoStack::pop);
output
}
}

View File

@@ -0,0 +1,215 @@
use crate::{
serde::{
de::{
error_utils::make_custom_error,
helpers::ExpectedValues,
registration_utils::try_get_registration,
struct_utils::{visit_struct, visit_struct_seq},
tuple_utils::{visit_tuple, TupleLikeInfo},
},
TypedReflectDeserializer,
},
DynamicEnum, DynamicStruct, DynamicTuple, DynamicVariant, EnumInfo, StructVariantInfo,
TupleVariantInfo, TypeRegistration, TypeRegistry, VariantInfo,
};
use core::{fmt, fmt::Formatter};
use serde::de::{DeserializeSeed, EnumAccess, Error, MapAccess, SeqAccess, VariantAccess, Visitor};
use super::ReflectDeserializerProcessor;
/// A [`Visitor`] for deserializing [`Enum`] values.
///
/// [`Enum`]: crate::Enum
pub(super) struct EnumVisitor<'a, P> {
pub enum_info: &'static EnumInfo,
pub registration: &'a TypeRegistration,
pub registry: &'a TypeRegistry,
pub processor: Option<&'a mut P>,
}
impl<'de, P: ReflectDeserializerProcessor> Visitor<'de> for EnumVisitor<'_, P> {
type Value = DynamicEnum;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("reflected enum value")
}
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
where
A: EnumAccess<'de>,
{
let mut dynamic_enum = DynamicEnum::default();
let (variant_info, variant) = data.variant_seed(VariantDeserializer {
enum_info: self.enum_info,
})?;
let value: DynamicVariant = match variant_info {
VariantInfo::Unit(..) => variant.unit_variant()?.into(),
VariantInfo::Struct(struct_info) => variant
.struct_variant(
struct_info.field_names(),
StructVariantVisitor {
struct_info,
registration: self.registration,
registry: self.registry,
processor: self.processor,
},
)?
.into(),
VariantInfo::Tuple(tuple_info) if tuple_info.field_len() == 1 => {
let registration = try_get_registration(
*TupleLikeInfo::field_at(tuple_info, 0)?.ty(),
self.registry,
)?;
let value =
variant.newtype_variant_seed(TypedReflectDeserializer::new_internal(
registration,
self.registry,
self.processor,
))?;
let mut dynamic_tuple = DynamicTuple::default();
dynamic_tuple.insert_boxed(value);
dynamic_tuple.into()
}
VariantInfo::Tuple(tuple_info) => variant
.tuple_variant(
tuple_info.field_len(),
TupleVariantVisitor {
tuple_info,
registration: self.registration,
registry: self.registry,
processor: self.processor,
},
)?
.into(),
};
let variant_name = variant_info.name();
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)
}
}
struct VariantDeserializer {
enum_info: &'static EnumInfo,
}
impl<'de> DeserializeSeed<'de> for VariantDeserializer {
type Value = &'static VariantInfo;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>,
{
struct VariantVisitor(&'static EnumInfo);
impl<'de> Visitor<'de> for VariantVisitor {
type Value = &'static VariantInfo;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("expected either a variant index or variant name")
}
fn visit_u32<E>(self, variant_index: u32) -> Result<Self::Value, E>
where
E: Error,
{
self.0.variant_at(variant_index as usize).ok_or_else(|| {
make_custom_error(format_args!(
"no variant found at index `{}` on enum `{}`",
variant_index,
self.0.type_path()
))
})
}
fn visit_str<E>(self, variant_name: &str) -> Result<Self::Value, E>
where
E: Error,
{
self.0.variant(variant_name).ok_or_else(|| {
let names = self.0.iter().map(VariantInfo::name);
make_custom_error(format_args!(
"unknown variant `{}`, expected one of {:?}",
variant_name,
ExpectedValues::from_iter(names)
))
})
}
}
deserializer.deserialize_identifier(VariantVisitor(self.enum_info))
}
}
struct StructVariantVisitor<'a, P> {
struct_info: &'static StructVariantInfo,
registration: &'a TypeRegistration,
registry: &'a TypeRegistry,
processor: Option<&'a mut P>,
}
impl<'de, P: ReflectDeserializerProcessor> Visitor<'de> for StructVariantVisitor<'_, P> {
type Value = DynamicStruct;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("reflected struct variant value")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
visit_struct_seq(
&mut seq,
self.struct_info,
self.registration,
self.registry,
self.processor,
)
}
fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error>
where
V: MapAccess<'de>,
{
visit_struct(
&mut map,
self.struct_info,
self.registration,
self.registry,
self.processor,
)
}
}
struct TupleVariantVisitor<'a, P> {
tuple_info: &'static TupleVariantInfo,
registration: &'a TypeRegistration,
registry: &'a TypeRegistry,
processor: Option<&'a mut P>,
}
impl<'de, P: ReflectDeserializerProcessor> Visitor<'de> for TupleVariantVisitor<'_, P> {
type Value = DynamicTuple;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("reflected tuple variant value")
}
fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
where
V: SeqAccess<'de>,
{
visit_tuple(
&mut seq,
self.tuple_info,
self.registration,
self.registry,
self.processor,
)
}
}

View File

@@ -0,0 +1,29 @@
use core::fmt::Display;
use serde::de::Error;
#[cfg(feature = "debug_stack")]
use std::thread_local;
#[cfg(feature = "debug_stack")]
thread_local! {
/// The thread-local [`TypeInfoStack`] used for debugging.
///
/// [`TypeInfoStack`]: crate::type_info_stack::TypeInfoStack
pub(super) static TYPE_INFO_STACK: core::cell::RefCell<crate::type_info_stack::TypeInfoStack> = const { core::cell::RefCell::new(
crate::type_info_stack::TypeInfoStack::new()
) };
}
/// A helper function for generating a custom deserialization error message.
///
/// This function should be preferred over [`Error::custom`] as it will include
/// other useful information, such as the [type info stack].
///
/// [type info stack]: crate::type_info_stack::TypeInfoStack
pub(super) fn make_custom_error<E: Error>(msg: impl Display) -> E {
#[cfg(feature = "debug_stack")]
return TYPE_INFO_STACK
.with_borrow(|stack| E::custom(format_args!("{} (stack: {:?})", msg, stack)));
#[cfg(not(feature = "debug_stack"))]
return E::custom(msg);
}

View File

@@ -0,0 +1,78 @@
use alloc::{
string::{String, ToString},
vec::Vec,
};
use core::{
fmt,
fmt::{Debug, Display, Formatter},
};
use serde::{
de::{Error, Visitor},
Deserialize,
};
/// A debug struct used for error messages that displays a list of expected values.
///
/// # Example
///
/// ```ignore (Can't import private struct from doctest)
/// let expected = vec!["foo", "bar", "baz"];
/// assert_eq!("`foo`, `bar`, `baz`", format!("{}", ExpectedValues(expected)));
/// ```
pub(super) struct ExpectedValues<T: Display>(pub Vec<T>);
impl<T: Display> FromIterator<T> for ExpectedValues<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
Self(iter.into_iter().collect())
}
}
impl<T: Display> Debug for ExpectedValues<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let len = self.0.len();
for (index, item) in self.0.iter().enumerate() {
write!(f, "`{item}`")?;
if index < len - 1 {
write!(f, ", ")?;
}
}
Ok(())
}
}
/// Represents a simple reflected identifier.
#[derive(Debug, Clone, Eq, PartialEq)]
pub(super) struct Ident(pub String);
impl<'de> Deserialize<'de> for Ident {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
struct IdentVisitor;
impl<'de> Visitor<'de> for IdentVisitor {
type Value = Ident;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("identifier")
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: Error,
{
Ok(Ident(value.to_string()))
}
fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
where
E: Error,
{
Ok(Ident(value))
}
}
deserializer.deserialize_identifier(IdentVisitor)
}
}

View File

@@ -0,0 +1,41 @@
use crate::{
serde::{de::registration_utils::try_get_registration, TypedReflectDeserializer},
DynamicList, ListInfo, TypeRegistry,
};
use core::{fmt, fmt::Formatter};
use serde::de::{SeqAccess, Visitor};
use super::ReflectDeserializerProcessor;
/// A [`Visitor`] for deserializing [`List`] values.
///
/// [`List`]: crate::List
pub(super) struct ListVisitor<'a, P> {
pub list_info: &'static ListInfo,
pub registry: &'a TypeRegistry,
pub processor: Option<&'a mut P>,
}
impl<'de, P: ReflectDeserializerProcessor> Visitor<'de> for ListVisitor<'_, P> {
type Value = DynamicList;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("reflected list value")
}
fn visit_seq<V>(mut self, mut seq: V) -> Result<Self::Value, V::Error>
where
V: SeqAccess<'de>,
{
let mut list = DynamicList::default();
let registration = try_get_registration(self.list_info.item_ty(), self.registry)?;
while let Some(value) = seq.next_element_seed(TypedReflectDeserializer::new_internal(
registration,
self.registry,
self.processor.as_deref_mut(),
))? {
list.push_box(value);
}
Ok(list)
}
}

View File

@@ -0,0 +1,48 @@
use crate::{
serde::{de::registration_utils::try_get_registration, TypedReflectDeserializer},
DynamicMap, Map, MapInfo, TypeRegistry,
};
use core::{fmt, fmt::Formatter};
use serde::de::{MapAccess, Visitor};
use super::ReflectDeserializerProcessor;
/// A [`Visitor`] for deserializing [`Map`] values.
///
/// [`Map`]: crate::Map
pub(super) struct MapVisitor<'a, P> {
pub map_info: &'static MapInfo,
pub registry: &'a TypeRegistry,
pub processor: Option<&'a mut P>,
}
impl<'de, P: ReflectDeserializerProcessor> Visitor<'de> for MapVisitor<'_, P> {
type Value = DynamicMap;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("reflected map value")
}
fn visit_map<V>(mut self, mut map: V) -> Result<Self::Value, V::Error>
where
V: MapAccess<'de>,
{
let mut dynamic_map = DynamicMap::default();
let key_registration = try_get_registration(self.map_info.key_ty(), self.registry)?;
let value_registration = try_get_registration(self.map_info.value_ty(), self.registry)?;
while let Some(key) = map.next_key_seed(TypedReflectDeserializer::new_internal(
key_registration,
self.registry,
self.processor.as_deref_mut(),
))? {
let value = map.next_value_seed(TypedReflectDeserializer::new_internal(
value_registration,
self.registry,
self.processor.as_deref_mut(),
))?;
dynamic_map.insert_boxed(key, value);
}
Ok(dynamic_map)
}
}

855
vendor/bevy_reflect/src/serde/de/mod.rs vendored Normal file
View File

@@ -0,0 +1,855 @@
pub use deserialize_with_registry::*;
pub use deserializer::*;
pub use processor::*;
pub use registrations::*;
mod arrays;
mod deserialize_with_registry;
mod deserializer;
mod enums;
mod error_utils;
mod helpers;
mod lists;
mod maps;
mod options;
mod processor;
mod registration_utils;
mod registrations;
mod sets;
mod struct_utils;
mod structs;
mod tuple_structs;
mod tuple_utils;
mod tuples;
#[cfg(test)]
mod tests {
use alloc::{
boxed::Box,
string::{String, ToString},
vec,
vec::Vec,
};
use core::{any::TypeId, f32::consts::PI, ops::RangeInclusive};
use serde::{de::DeserializeSeed, Deserialize};
use serde::{de::IgnoredAny, Deserializer};
use bevy_platform::collections::{HashMap, HashSet};
use crate::{
serde::{
ReflectDeserializer, ReflectDeserializerProcessor, ReflectSerializer,
TypedReflectDeserializer,
},
DynamicEnum, FromReflect, PartialReflect, Reflect, ReflectDeserialize, TypeRegistration,
TypeRegistry,
};
#[derive(Reflect, Debug, PartialEq)]
struct MyStruct {
primitive_value: i8,
option_value: Option<String>,
option_value_complex: Option<SomeStruct>,
tuple_value: (f32, usize),
list_value: Vec<i32>,
array_value: [i32; 5],
map_value: HashMap<u8, usize>,
set_value: HashSet<u8>,
struct_value: SomeStruct,
tuple_struct_value: SomeTupleStruct,
unit_struct: SomeUnitStruct,
unit_enum: SomeEnum,
newtype_enum: SomeEnum,
tuple_enum: SomeEnum,
struct_enum: SomeEnum,
ignored_struct: SomeIgnoredStruct,
ignored_tuple_struct: SomeIgnoredTupleStruct,
ignored_struct_variant: SomeIgnoredEnum,
ignored_tuple_variant: SomeIgnoredEnum,
custom_deserialize: CustomDeserialize,
}
#[derive(Reflect, Debug, PartialEq)]
struct SomeStruct {
foo: i64,
}
#[derive(Reflect, Debug, PartialEq)]
struct SomeTupleStruct(String);
#[derive(Reflect, Debug, PartialEq)]
struct SomeUnitStruct;
#[derive(Reflect, Debug, PartialEq)]
struct SomeIgnoredStruct {
#[reflect(ignore)]
ignored: i32,
}
#[derive(Reflect, Debug, PartialEq)]
struct SomeIgnoredTupleStruct(#[reflect(ignore)] i32);
#[derive(Reflect, Debug, PartialEq, Deserialize)]
struct SomeDeserializableStruct {
foo: i64,
}
/// Implements a custom deserialize using `#[reflect(Deserialize)]`.
///
/// For testing purposes, this is just the auto-generated one from deriving.
#[derive(Reflect, Debug, PartialEq, Deserialize)]
#[reflect(Deserialize)]
struct CustomDeserialize {
value: usize,
#[serde(alias = "renamed")]
inner_struct: SomeDeserializableStruct,
}
#[derive(Reflect, Debug, PartialEq)]
enum SomeEnum {
Unit,
NewType(usize),
Tuple(f32, f32),
Struct { foo: String },
}
#[derive(Reflect, Debug, PartialEq)]
enum SomeIgnoredEnum {
Tuple(#[reflect(ignore)] f32, #[reflect(ignore)] f32),
Struct {
#[reflect(ignore)]
foo: String,
},
}
fn get_registry() -> TypeRegistry {
let mut registry = TypeRegistry::default();
registry.register::<MyStruct>();
registry.register::<SomeStruct>();
registry.register::<SomeTupleStruct>();
registry.register::<SomeUnitStruct>();
registry.register::<SomeIgnoredStruct>();
registry.register::<SomeIgnoredTupleStruct>();
registry.register::<CustomDeserialize>();
registry.register::<SomeDeserializableStruct>();
registry.register::<SomeEnum>();
registry.register::<SomeIgnoredEnum>();
registry.register::<i8>();
registry.register::<String>();
registry.register::<i64>();
registry.register::<f32>();
registry.register::<usize>();
registry.register::<i32>();
registry.register::<u8>();
registry.register::<(f32, usize)>();
registry.register::<[i32; 5]>();
registry.register::<Vec<i32>>();
registry.register::<HashMap<u8, usize>>();
registry.register::<HashSet<u8>>();
registry.register::<Option<SomeStruct>>();
registry.register::<Option<String>>();
registry.register_type_data::<Option<String>, ReflectDeserialize>();
registry
}
fn get_my_struct() -> MyStruct {
let mut map = <HashMap<_, _>>::default();
map.insert(64, 32);
let mut set = <HashSet<_>>::default();
set.insert(64);
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,
set_value: set,
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 },
},
}
}
#[test]
fn should_deserialize() {
let expected = get_my_struct();
let registry = get_registry();
let input = r#"{
"bevy_reflect::serde::de::tests::MyStruct": (
primitive_value: 123,
option_value: Some("Hello world!"),
option_value_complex: Some((
foo: 123,
)),
tuple_value: (3.1415927, 1337),
list_value: [
-2,
-1,
0,
1,
2,
],
array_value: (-2, -1, 0, 1, 2),
map_value: {
64: 32,
},
set_value: [
64,
],
struct_value: (
foo: 999999999,
),
tuple_struct_value: ("Tuple Struct"),
unit_struct: (),
unit_enum: Unit,
newtype_enum: NewType(123),
tuple_enum: Tuple(1.23, 3.21),
struct_enum: Struct(
foo: "Struct variant value",
),
ignored_struct: (),
ignored_tuple_struct: (),
ignored_struct_variant: Struct(),
ignored_tuple_variant: Tuple(),
custom_deserialize: (
value: 100,
renamed: (
foo: 101,
),
),
),
}"#;
let reflect_deserializer = ReflectDeserializer::new(&registry);
let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap();
let dynamic_output = reflect_deserializer
.deserialize(&mut ron_deserializer)
.unwrap();
let output = <MyStruct as FromReflect>::from_reflect(dynamic_output.as_ref()).unwrap();
assert_eq!(expected, output);
}
#[test]
fn should_deserialize_value() {
let input = r#"{
"f32": 1.23,
}"#;
let registry = get_registry();
let reflect_deserializer = ReflectDeserializer::new(&registry);
let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap();
let dynamic_output = reflect_deserializer
.deserialize(&mut ron_deserializer)
.unwrap();
let output = dynamic_output
.try_take::<f32>()
.expect("underlying type should be f32");
assert_eq!(1.23, output);
}
#[test]
fn should_deserialized_typed() {
#[derive(Reflect, Debug, PartialEq)]
struct Foo {
bar: i32,
}
let expected = Foo { bar: 123 };
let input = r#"(
bar: 123
)"#;
let mut registry = get_registry();
registry.register::<Foo>();
let registration = registry.get(TypeId::of::<Foo>()).unwrap();
let reflect_deserializer = TypedReflectDeserializer::new(registration, &registry);
let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap();
let dynamic_output = reflect_deserializer
.deserialize(&mut ron_deserializer)
.unwrap();
let output =
<Foo as FromReflect>::from_reflect(dynamic_output.as_partial_reflect()).unwrap();
assert_eq!(expected, output);
}
#[test]
fn should_deserialize_option() {
#[derive(Reflect, Debug, PartialEq)]
struct OptionTest {
none: Option<()>,
simple: Option<String>,
complex: Option<SomeStruct>,
}
let expected = OptionTest {
none: None,
simple: Some(String::from("Hello world!")),
complex: Some(SomeStruct { foo: 123 }),
};
let mut registry = get_registry();
registry.register::<OptionTest>();
registry.register::<Option<()>>();
// === Normal === //
let input = r#"{
"bevy_reflect::serde::de::tests::OptionTest": (
none: None,
simple: Some("Hello world!"),
complex: Some((
foo: 123,
)),
),
}"#;
let reflect_deserializer = ReflectDeserializer::new(&registry);
let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap();
let dynamic_output = reflect_deserializer
.deserialize(&mut ron_deserializer)
.unwrap();
let output = <OptionTest as FromReflect>::from_reflect(dynamic_output.as_ref()).unwrap();
assert_eq!(expected, output, "failed to deserialize Options");
// === Implicit Some === //
let input = r#"
#![enable(implicit_some)]
{
"bevy_reflect::serde::de::tests::OptionTest": (
none: None,
simple: "Hello world!",
complex: (
foo: 123,
),
),
}"#;
let reflect_deserializer = ReflectDeserializer::new(&registry);
let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap();
let dynamic_output = reflect_deserializer
.deserialize(&mut ron_deserializer)
.unwrap();
let output = <OptionTest as FromReflect>::from_reflect(dynamic_output.as_ref()).unwrap();
assert_eq!(
expected, output,
"failed to deserialize Options with implicit Some"
);
}
#[test]
fn enum_should_deserialize() {
#[derive(Reflect)]
enum MyEnum {
Unit,
NewType(usize),
Tuple(f32, f32),
Struct { value: String },
}
let mut registry = get_registry();
registry.register::<MyEnum>();
// === Unit Variant === //
let input = r#"{
"bevy_reflect::serde::de::tests::MyEnum": Unit,
}"#;
let reflect_deserializer = ReflectDeserializer::new(&registry);
let mut deserializer = ron::de::Deserializer::from_str(input).unwrap();
let output = reflect_deserializer.deserialize(&mut deserializer).unwrap();
let expected = DynamicEnum::from(MyEnum::Unit);
assert!(expected.reflect_partial_eq(output.as_ref()).unwrap());
// === NewType Variant === //
let input = r#"{
"bevy_reflect::serde::de::tests::MyEnum": NewType(123),
}"#;
let reflect_deserializer = ReflectDeserializer::new(&registry);
let mut deserializer = ron::de::Deserializer::from_str(input).unwrap();
let output = reflect_deserializer.deserialize(&mut deserializer).unwrap();
let expected = DynamicEnum::from(MyEnum::NewType(123));
assert!(expected.reflect_partial_eq(output.as_ref()).unwrap());
// === Tuple Variant === //
let input = r#"{
"bevy_reflect::serde::de::tests::MyEnum": Tuple(1.23, 3.21),
}"#;
let reflect_deserializer = ReflectDeserializer::new(&registry);
let mut deserializer = ron::de::Deserializer::from_str(input).unwrap();
let output = reflect_deserializer.deserialize(&mut deserializer).unwrap();
let expected = DynamicEnum::from(MyEnum::Tuple(1.23, 3.21));
assert!(expected
.reflect_partial_eq(output.as_partial_reflect())
.unwrap());
// === Struct Variant === //
let input = r#"{
"bevy_reflect::serde::de::tests::MyEnum": Struct(
value: "I <3 Enums",
),
}"#;
let reflect_deserializer = ReflectDeserializer::new(&registry);
let mut deserializer = ron::de::Deserializer::from_str(input).unwrap();
let output = reflect_deserializer.deserialize(&mut deserializer).unwrap();
let expected = DynamicEnum::from(MyEnum::Struct {
value: String::from("I <3 Enums"),
});
assert!(expected
.reflect_partial_eq(output.as_partial_reflect())
.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, &registry);
let serialized1 = ron::ser::to_string(&serializer1).unwrap();
let mut deserializer = ron::de::Deserializer::from_str(&serialized1).unwrap();
let reflect_deserializer = ReflectDeserializer::new(&registry);
let input2 = reflect_deserializer.deserialize(&mut deserializer).unwrap();
let serializer2 = ReflectSerializer::new(input2.as_partial_reflect(), &registry);
let serialized2 = ron::ser::to_string(&serializer2).unwrap();
assert_eq!(serialized1, serialized2);
}
#[test]
fn should_deserialize_non_self_describing_binary() {
let expected = get_my_struct();
let registry = get_registry();
let input = vec![
1, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 98, 101, 118, 121, 95, 114, 101, 102,
108, 101, 99, 116, 58, 58, 115, 101, 114, 100, 101, 58, 58, 100, 101, 58, 58, 116, 101,
115, 116, 115, 58, 58, 77, 121, 83, 116, 114, 117, 99, 116, 123, 1, 12, 0, 0, 0, 0, 0,
0, 0, 72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33, 1, 123, 0, 0, 0, 0, 0,
0, 0, 219, 15, 73, 64, 57, 5, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 254, 255, 255,
255, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 254, 255, 255, 255, 255,
255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 32, 0,
0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 255, 201, 154, 59, 0, 0, 0, 0, 12, 0, 0,
0, 0, 0, 0, 0, 84, 117, 112, 108, 101, 32, 83, 116, 114, 117, 99, 116, 0, 0, 0, 0, 1,
0, 0, 0, 123, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 164, 112, 157, 63, 164, 112, 77, 64, 3,
0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 83, 116, 114, 117, 99, 116, 32, 118, 97, 114, 105,
97, 110, 116, 32, 118, 97, 108, 117, 101, 1, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0,
0, 0, 101, 0, 0, 0, 0, 0, 0, 0,
];
let deserializer = ReflectDeserializer::new(&registry);
let config = bincode::config::standard().with_fixed_int_encoding();
let (dynamic_output, _read_bytes) =
bincode::serde::seed_decode_from_slice(deserializer, &input, config).unwrap();
let output = <MyStruct as FromReflect>::from_reflect(dynamic_output.as_ref()).unwrap();
assert_eq!(expected, output);
}
#[test]
fn should_deserialize_self_describing_binary() {
let expected = get_my_struct();
let registry = get_registry();
let input = vec![
129, 217, 40, 98, 101, 118, 121, 95, 114, 101, 102, 108, 101, 99, 116, 58, 58, 115,
101, 114, 100, 101, 58, 58, 100, 101, 58, 58, 116, 101, 115, 116, 115, 58, 58, 77, 121,
83, 116, 114, 117, 99, 116, 220, 0, 20, 123, 172, 72, 101, 108, 108, 111, 32, 119, 111,
114, 108, 100, 33, 145, 123, 146, 202, 64, 73, 15, 219, 205, 5, 57, 149, 254, 255, 0,
1, 2, 149, 254, 255, 0, 1, 2, 129, 64, 32, 145, 64, 145, 206, 59, 154, 201, 255, 172,
84, 117, 112, 108, 101, 32, 83, 116, 114, 117, 99, 116, 144, 164, 85, 110, 105, 116,
129, 167, 78, 101, 119, 84, 121, 112, 101, 123, 129, 165, 84, 117, 112, 108, 101, 146,
202, 63, 157, 112, 164, 202, 64, 77, 112, 164, 129, 166, 83, 116, 114, 117, 99, 116,
145, 180, 83, 116, 114, 117, 99, 116, 32, 118, 97, 114, 105, 97, 110, 116, 32, 118, 97,
108, 117, 101, 144, 144, 129, 166, 83, 116, 114, 117, 99, 116, 144, 129, 165, 84, 117,
112, 108, 101, 144, 146, 100, 145, 101,
];
let mut reader = std::io::BufReader::new(input.as_slice());
let deserializer = ReflectDeserializer::new(&registry);
let dynamic_output = deserializer
.deserialize(&mut rmp_serde::Deserializer::new(&mut reader))
.unwrap();
let output = <MyStruct as FromReflect>::from_reflect(dynamic_output.as_ref()).unwrap();
assert_eq!(expected, output);
}
#[test]
fn should_return_error_if_missing_type_data() {
let mut registry = TypeRegistry::new();
registry.register::<RangeInclusive<f32>>();
let input = r#"{"core::ops::RangeInclusive<f32>":(start:0.0,end:1.0)}"#;
let mut deserializer = ron::de::Deserializer::from_str(input).unwrap();
let reflect_deserializer = ReflectDeserializer::new(&registry);
let error = reflect_deserializer
.deserialize(&mut deserializer)
.unwrap_err();
#[cfg(feature = "debug_stack")]
assert_eq!(error, ron::Error::Message("type `core::ops::RangeInclusive<f32>` did not register the `ReflectDeserialize` type data. For certain types, this may need to be registered manually using `register_type_data` (stack: `core::ops::RangeInclusive<f32>`)".to_string()));
#[cfg(not(feature = "debug_stack"))]
assert_eq!(error, ron::Error::Message("type `core::ops::RangeInclusive<f32>` did not register the `ReflectDeserialize` type data. For certain types, this may need to be registered manually using `register_type_data`".to_string()));
}
#[test]
fn should_use_processor_for_custom_deserialization() {
#[derive(Reflect, Debug, PartialEq)]
struct Foo {
bar: i32,
qux: i64,
}
struct FooProcessor;
impl ReflectDeserializerProcessor for FooProcessor {
fn try_deserialize<'de, D>(
&mut self,
registration: &TypeRegistration,
_: &TypeRegistry,
deserializer: D,
) -> Result<Result<Box<dyn PartialReflect>, D>, D::Error>
where
D: Deserializer<'de>,
{
if registration.type_id() == TypeId::of::<i64>() {
let _ = deserializer.deserialize_ignored_any(IgnoredAny);
Ok(Ok(Box::new(456_i64)))
} else {
Ok(Err(deserializer))
}
}
}
let expected = Foo { bar: 123, qux: 456 };
let input = r#"(
bar: 123,
qux: 123,
)"#;
let mut registry = get_registry();
registry.register::<Foo>();
let registration = registry.get(TypeId::of::<Foo>()).unwrap();
let mut processor = FooProcessor;
let reflect_deserializer =
TypedReflectDeserializer::with_processor(registration, &registry, &mut processor);
let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap();
let dynamic_output = reflect_deserializer
.deserialize(&mut ron_deserializer)
.unwrap();
let output =
<Foo as FromReflect>::from_reflect(dynamic_output.as_partial_reflect()).unwrap();
assert_eq!(expected, output);
}
#[test]
fn should_use_processor_for_multiple_registrations() {
#[derive(Reflect, Debug, PartialEq)]
struct Foo {
bar: i32,
qux: i64,
}
struct FooProcessor;
impl ReflectDeserializerProcessor for FooProcessor {
fn try_deserialize<'de, D>(
&mut self,
registration: &TypeRegistration,
_: &TypeRegistry,
deserializer: D,
) -> Result<Result<Box<dyn PartialReflect>, D>, D::Error>
where
D: Deserializer<'de>,
{
if registration.type_id() == TypeId::of::<i32>() {
let _ = deserializer.deserialize_ignored_any(IgnoredAny);
Ok(Ok(Box::new(123_i32)))
} else if registration.type_id() == TypeId::of::<i64>() {
let _ = deserializer.deserialize_ignored_any(IgnoredAny);
Ok(Ok(Box::new(456_i64)))
} else {
Ok(Err(deserializer))
}
}
}
let expected = Foo { bar: 123, qux: 456 };
let input = r#"(
bar: 0,
qux: 0,
)"#;
let mut registry = get_registry();
registry.register::<Foo>();
let registration = registry.get(TypeId::of::<Foo>()).unwrap();
let mut processor = FooProcessor;
let reflect_deserializer =
TypedReflectDeserializer::with_processor(registration, &registry, &mut processor);
let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap();
let dynamic_output = reflect_deserializer
.deserialize(&mut ron_deserializer)
.unwrap();
let output =
<Foo as FromReflect>::from_reflect(dynamic_output.as_partial_reflect()).unwrap();
assert_eq!(expected, output);
}
#[test]
fn should_propagate_processor_deserialize_error() {
struct ErroringProcessor;
impl ReflectDeserializerProcessor for ErroringProcessor {
fn try_deserialize<'de, D>(
&mut self,
registration: &TypeRegistration,
_: &TypeRegistry,
deserializer: D,
) -> Result<Result<Box<dyn PartialReflect>, D>, D::Error>
where
D: Deserializer<'de>,
{
if registration.type_id() == TypeId::of::<i32>() {
Err(serde::de::Error::custom("my custom deserialize error"))
} else {
Ok(Err(deserializer))
}
}
}
let registry = get_registry();
let input = r#"{"i32":123}"#;
let mut deserializer = ron::de::Deserializer::from_str(input).unwrap();
let mut processor = ErroringProcessor;
let reflect_deserializer = ReflectDeserializer::with_processor(&registry, &mut processor);
let error = reflect_deserializer
.deserialize(&mut deserializer)
.unwrap_err();
#[cfg(feature = "debug_stack")]
assert_eq!(
error,
ron::Error::Message("my custom deserialize error (stack: `i32`)".to_string())
);
#[cfg(not(feature = "debug_stack"))]
assert_eq!(
error,
ron::Error::Message("my custom deserialize error".to_string())
);
}
#[test]
fn should_access_local_scope_in_processor() {
struct ValueCountingProcessor<'a> {
values_found: &'a mut usize,
}
impl ReflectDeserializerProcessor for ValueCountingProcessor<'_> {
fn try_deserialize<'de, D>(
&mut self,
_: &TypeRegistration,
_: &TypeRegistry,
deserializer: D,
) -> Result<Result<Box<dyn PartialReflect>, D>, D::Error>
where
D: Deserializer<'de>,
{
let _ = deserializer.deserialize_ignored_any(IgnoredAny)?;
*self.values_found += 1;
Ok(Ok(Box::new(123_i32)))
}
}
let registry = get_registry();
let input = r#"{"i32":0}"#;
let mut values_found = 0_usize;
let mut deserializer_processor = ValueCountingProcessor {
values_found: &mut values_found,
};
let mut deserializer = ron::de::Deserializer::from_str(input).unwrap();
let reflect_deserializer =
ReflectDeserializer::with_processor(&registry, &mut deserializer_processor);
reflect_deserializer.deserialize(&mut deserializer).unwrap();
assert_eq!(1, values_found);
}
#[test]
fn should_fail_from_reflect_if_processor_returns_wrong_typed_value() {
#[derive(Reflect, Debug, PartialEq)]
struct Foo {
bar: i32,
qux: i64,
}
struct WrongTypeProcessor;
impl ReflectDeserializerProcessor for WrongTypeProcessor {
fn try_deserialize<'de, D>(
&mut self,
registration: &TypeRegistration,
_registry: &TypeRegistry,
deserializer: D,
) -> Result<Result<Box<dyn PartialReflect>, D>, D::Error>
where
D: Deserializer<'de>,
{
if registration.type_id() == TypeId::of::<i32>() {
let _ = deserializer.deserialize_ignored_any(IgnoredAny);
Ok(Ok(Box::new(42_i64)))
} else {
Ok(Err(deserializer))
}
}
}
let input = r#"(
bar: 123,
qux: 123,
)"#;
let mut registry = get_registry();
registry.register::<Foo>();
let registration = registry.get(TypeId::of::<Foo>()).unwrap();
let mut processor = WrongTypeProcessor;
let reflect_deserializer =
TypedReflectDeserializer::with_processor(registration, &registry, &mut processor);
let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap();
let dynamic_output = reflect_deserializer
.deserialize(&mut ron_deserializer)
.unwrap();
assert!(<Foo as FromReflect>::from_reflect(dynamic_output.as_partial_reflect()).is_none());
}
#[cfg(feature = "functions")]
mod functions {
use super::*;
use crate::func::DynamicFunction;
#[test]
fn should_not_deserialize_function() {
#[derive(Reflect)]
#[reflect(from_reflect = false)]
struct MyStruct {
func: DynamicFunction<'static>,
}
let mut registry = TypeRegistry::new();
registry.register::<MyStruct>();
let input = r#"{
"bevy_reflect::serde::de::tests::functions::MyStruct": (
func: (),
),
}"#;
let reflect_deserializer = ReflectDeserializer::new(&registry);
let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap();
let error = reflect_deserializer
.deserialize(&mut ron_deserializer)
.unwrap_err();
#[cfg(feature = "debug_stack")]
assert_eq!(
error,
ron::Error::Message(
"no registration found for type `bevy_reflect::DynamicFunction` (stack: `bevy_reflect::serde::de::tests::functions::MyStruct`)"
.to_string()
)
);
#[cfg(not(feature = "debug_stack"))]
assert_eq!(
error,
ron::Error::Message(
"no registration found for type `bevy_reflect::DynamicFunction`".to_string()
)
);
}
}
#[cfg(feature = "debug_stack")]
mod debug_stack {
use super::*;
#[test]
fn should_report_context_in_errors() {
#[derive(Reflect)]
struct Foo {
bar: Bar,
}
#[derive(Reflect)]
struct Bar {
some_other_field: Option<u32>,
baz: Baz,
}
#[derive(Reflect)]
struct Baz {
value: Vec<RangeInclusive<f32>>,
}
let mut registry = TypeRegistry::new();
registry.register::<Foo>();
registry.register::<Bar>();
registry.register::<Baz>();
registry.register::<RangeInclusive<f32>>();
let input = r#"{"bevy_reflect::serde::de::tests::debug_stack::Foo":(bar:(some_other_field:Some(123),baz:(value:[(start:0.0,end:1.0)])))}"#;
let mut deserializer = ron::de::Deserializer::from_str(input).unwrap();
let reflect_deserializer = ReflectDeserializer::new(&registry);
let error = reflect_deserializer
.deserialize(&mut deserializer)
.unwrap_err();
assert_eq!(
error,
ron::Error::Message(
"type `core::ops::RangeInclusive<f32>` did not register the `ReflectDeserialize` type data. For certain types, this may need to be registered manually using `register_type_data` (stack: `bevy_reflect::serde::de::tests::debug_stack::Foo` -> `bevy_reflect::serde::de::tests::debug_stack::Bar` -> `bevy_reflect::serde::de::tests::debug_stack::Baz` -> `alloc::vec::Vec<core::ops::RangeInclusive<f32>>` -> `core::ops::RangeInclusive<f32>`)".to_string()
)
);
}
}
}

View File

@@ -0,0 +1,63 @@
use crate::{
serde::{
de::{error_utils::make_custom_error, registration_utils::try_get_registration},
TypedReflectDeserializer,
},
DynamicEnum, DynamicTuple, EnumInfo, TypeRegistry, VariantInfo,
};
use core::{fmt, fmt::Formatter};
use serde::de::{DeserializeSeed, Error, Visitor};
use super::ReflectDeserializerProcessor;
/// A [`Visitor`] for deserializing [`Option`] values.
pub(super) struct OptionVisitor<'a, P> {
pub enum_info: &'static EnumInfo,
pub registry: &'a TypeRegistry,
pub processor: Option<&'a mut P>,
}
impl<'de, P: ReflectDeserializerProcessor> Visitor<'de> for OptionVisitor<'_, P> {
type Value = DynamicEnum;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("reflected option value of type ")?;
formatter.write_str(self.enum_info.type_path())
}
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: Error,
{
let mut option = DynamicEnum::default();
option.set_variant("None", ());
Ok(option)
}
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>,
{
let variant_info = self.enum_info.variant("Some").unwrap();
match variant_info {
VariantInfo::Tuple(tuple_info) if tuple_info.field_len() == 1 => {
let field = tuple_info.field_at(0).unwrap();
let registration = try_get_registration(*field.ty(), self.registry)?;
let de = TypedReflectDeserializer::new_internal(
registration,
self.registry,
self.processor,
);
let mut value = DynamicTuple::default();
value.insert_boxed(de.deserialize(deserializer)?);
let mut option = DynamicEnum::default();
option.set_variant("Some", value);
Ok(option)
}
info => Err(make_custom_error(format_args!(
"invalid variant, expected `Some` but got `{}`",
info.name()
))),
}
}
}

View File

@@ -0,0 +1,217 @@
use crate::{PartialReflect, TypeRegistration, TypeRegistry};
use alloc::boxed::Box;
/// Allows overriding the default deserialization behavior of
/// [`ReflectDeserializer`] and [`TypedReflectDeserializer`] for specific
/// [`TypeRegistration`]s.
///
/// When deserializing a reflected value, you may want to override the default
/// behavior and use your own logic for deserialization. This logic may also
/// be context-dependent, and only apply for a single use of your
/// [`ReflectDeserializer`]. To achieve this, you can create a processor and
/// pass it in to your deserializer.
///
/// Whenever the deserializer attempts to deserialize a value, it will first
/// call [`try_deserialize`] on your processor, which may take ownership of the
/// deserializer and give back a [`Box<dyn PartialReflect>`], or return
/// ownership of the deserializer back, and continue with the default logic.
///
/// The serialization equivalent of this is [`ReflectSerializerProcessor`].
///
/// # Compared to [`DeserializeWithRegistry`]
///
/// [`DeserializeWithRegistry`] allows you to define how your type will be
/// deserialized by a [`TypedReflectDeserializer`], given the extra context of
/// the [`TypeRegistry`]. If your type can be deserialized entirely from that,
/// then you should prefer implementing that trait instead of using a processor.
///
/// However, you may need more context-dependent data which is only present in
/// the scope where you create the [`TypedReflectDeserializer`]. For example, in
/// an asset loader, the `&mut LoadContext` you get is only valid from within
/// the `load` function. This is where a processor is useful, as the processor
/// can capture local variables.
///
/// A [`ReflectDeserializerProcessor`] always takes priority over a
/// [`DeserializeWithRegistry`] implementation, so this is also useful for
/// overriding deserialization behavior if you need to do something custom.
///
/// # Examples
///
/// Deserializing a reflected value in an asset loader, and replacing asset
/// handles with a loaded equivalent:
///
/// ```
/// # use bevy_reflect::serde::{ReflectDeserializer, ReflectDeserializerProcessor};
/// # use bevy_reflect::{PartialReflect, Reflect, TypeData, TypeRegistration, TypeRegistry};
/// # use serde::de::{DeserializeSeed, Deserializer, Visitor};
/// # use std::marker::PhantomData;
/// #
/// # #[derive(Debug, Clone, Reflect)]
/// # struct LoadedUntypedAsset;
/// # #[derive(Debug, Clone, Reflect)]
/// # struct Handle<T: Reflect>(T);
/// # #[derive(Debug, Clone, Reflect)]
/// # struct Mesh;
/// #
/// # struct LoadContext;
/// # impl LoadContext {
/// # fn load(&mut self) -> &mut Self { unimplemented!() }
/// # fn with_asset_type_id(&mut self, (): ()) -> &mut Self { unimplemented!() }
/// # fn untyped(&mut self) -> &mut Self { unimplemented!() }
/// # fn load_asset(&mut self, (): ()) -> Handle<LoadedUntypedAsset> { unimplemented!() }
/// # }
/// #
/// # struct ReflectHandle;
/// # impl TypeData for ReflectHandle {
/// # fn clone_type_data(&self) -> Box<dyn TypeData> {
/// # unimplemented!()
/// # }
/// # }
/// # impl ReflectHandle {
/// # fn asset_type_id(&self) {
/// # unimplemented!()
/// # }
/// # }
/// #
/// # struct AssetPathVisitor;
/// # impl<'de> Visitor<'de> for AssetPathVisitor {
/// # type Value = ();
/// # fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { unimplemented!() }
/// # }
/// # type AssetError = Box<dyn core::error::Error>;
/// #[derive(Debug, Clone, Reflect)]
/// struct MyAsset {
/// name: String,
/// mesh: Handle<Mesh>,
/// }
///
/// fn load(
/// asset_bytes: &[u8],
/// type_registry: &TypeRegistry,
/// load_context: &mut LoadContext,
/// ) -> Result<MyAsset, AssetError> {
/// struct HandleProcessor<'a> {
/// load_context: &'a mut LoadContext,
/// }
///
/// impl ReflectDeserializerProcessor for HandleProcessor<'_> {
/// fn try_deserialize<'de, D>(
/// &mut self,
/// registration: &TypeRegistration,
/// _registry: &TypeRegistry,
/// deserializer: D,
/// ) -> Result<Result<Box<dyn PartialReflect>, D>, D::Error>
/// where
/// D: Deserializer<'de>,
/// {
/// let Some(reflect_handle) = registration.data::<ReflectHandle>() else {
/// // we don't want to deserialize this - give the deserializer back
/// return Ok(Err(deserializer));
/// };
///
/// let asset_type_id = reflect_handle.asset_type_id();
/// let asset_path = deserializer.deserialize_str(AssetPathVisitor)?;
///
/// let handle: Handle<LoadedUntypedAsset> = self.load_context
/// .load()
/// .with_asset_type_id(asset_type_id)
/// .untyped()
/// .load_asset(asset_path);
/// # let _: Result<_, ()> = {
/// Ok(Box::new(handle))
/// # };
/// # unimplemented!()
/// }
/// }
///
/// let mut ron_deserializer = ron::Deserializer::from_bytes(asset_bytes)?;
/// let mut processor = HandleProcessor { load_context };
/// let reflect_deserializer =
/// ReflectDeserializer::with_processor(type_registry, &mut processor);
/// let asset = reflect_deserializer.deserialize(&mut ron_deserializer)?;
/// # unimplemented!()
/// }
/// ```
///
/// [`ReflectDeserializer`]: crate::serde::ReflectDeserializer
/// [`TypedReflectDeserializer`]: crate::serde::TypedReflectDeserializer
/// [`try_deserialize`]: Self::try_deserialize
/// [`DeserializeWithRegistry`]: crate::serde::DeserializeWithRegistry
/// [`ReflectSerializerProcessor`]: crate::serde::ReflectSerializerProcessor
pub trait ReflectDeserializerProcessor {
/// Attempts to deserialize the value which a [`TypedReflectDeserializer`]
/// is currently looking at, and knows the type of.
///
/// If you've read the `registration` and want to override the default
/// deserialization, return `Ok(Ok(value))` with the boxed reflected value
/// that you want to assign this value to. The type inside the box must
/// be the same one as the `registration` is for, otherwise future
/// reflection operations (such as using [`FromReflect`] to convert the
/// resulting [`Box<dyn PartialReflect>`] into a concrete type) will fail.
///
/// If you don't want to override the deserialization, return ownership of
/// the deserializer back via `Ok(Err(deserializer))`.
///
/// Note that, if you do want to return a value, you *must* read from the
/// deserializer passed to this function (you are free to ignore the result
/// though). Otherwise, the deserializer will be in an inconsistent state,
/// and future value parsing will fail.
///
/// # Examples
///
/// Correct way to return a constant value (not using any output from the
/// deserializer):
///
/// ```
/// # use bevy_reflect::{TypeRegistration, PartialReflect, TypeRegistry};
/// # use bevy_reflect::serde::ReflectDeserializerProcessor;
/// # use core::any::TypeId;
/// use serde::de::IgnoredAny;
///
/// struct ConstantI32Processor;
///
/// impl ReflectDeserializerProcessor for ConstantI32Processor {
/// fn try_deserialize<'de, D>(
/// &mut self,
/// registration: &TypeRegistration,
/// _registry: &TypeRegistry,
/// deserializer: D,
/// ) -> Result<Result<Box<dyn PartialReflect>, D>, D::Error>
/// where
/// D: serde::Deserializer<'de>
/// {
/// if registration.type_id() == TypeId::of::<i32>() {
/// _ = deserializer.deserialize_ignored_any(IgnoredAny);
/// Ok(Ok(Box::new(42_i32)))
/// } else {
/// Ok(Err(deserializer))
/// }
/// }
/// }
/// ```
///
/// [`TypedReflectDeserializer`]: crate::serde::TypedReflectDeserializer
/// [`FromReflect`]: crate::FromReflect
fn try_deserialize<'de, D>(
&mut self,
registration: &TypeRegistration,
registry: &TypeRegistry,
deserializer: D,
) -> Result<Result<Box<dyn PartialReflect>, D>, D::Error>
where
D: serde::Deserializer<'de>;
}
impl ReflectDeserializerProcessor for () {
fn try_deserialize<'de, D>(
&mut self,
_registration: &TypeRegistration,
_registry: &TypeRegistry,
deserializer: D,
) -> Result<Result<Box<dyn PartialReflect>, D>, D::Error>
where
D: serde::Deserializer<'de>,
{
Ok(Err(deserializer))
}
}

View File

@@ -0,0 +1,15 @@
use crate::{serde::de::error_utils::make_custom_error, Type, TypeRegistration, TypeRegistry};
use serde::de::Error;
/// Attempts to find the [`TypeRegistration`] for a given [type].
///
/// [type]: Type
pub(super) fn try_get_registration<E: Error>(
ty: Type,
registry: &TypeRegistry,
) -> Result<&TypeRegistration, E> {
let registration = registry.get(ty.id()).ok_or_else(|| {
make_custom_error(format_args!("no registration found for type `{ty:?}`"))
})?;
Ok(registration)
}

View File

@@ -0,0 +1,51 @@
use crate::{serde::de::error_utils::make_custom_error, TypeRegistration, TypeRegistry};
use core::{fmt, fmt::Formatter};
use serde::de::{DeserializeSeed, Error, Visitor};
/// A deserializer for type registrations.
///
/// This will return a [`&TypeRegistration`] corresponding to the given type.
/// This deserializer expects a string containing the _full_ [type path] of the
/// type to find the `TypeRegistration` of.
///
/// [`&TypeRegistration`]: TypeRegistration
/// [type path]: crate::TypePath::type_path
pub struct TypeRegistrationDeserializer<'a> {
registry: &'a TypeRegistry,
}
impl<'a> TypeRegistrationDeserializer<'a> {
pub fn new(registry: &'a TypeRegistry) -> Self {
Self { registry }
}
}
impl<'a, 'de> DeserializeSeed<'de> for TypeRegistrationDeserializer<'a> {
type Value = &'a TypeRegistration;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>,
{
struct TypeRegistrationVisitor<'a>(&'a TypeRegistry);
impl<'de, 'a> Visitor<'de> for TypeRegistrationVisitor<'a> {
type Value = &'a TypeRegistration;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("string containing `type` entry for the reflected value")
}
fn visit_str<E>(self, type_path: &str) -> Result<Self::Value, E>
where
E: Error,
{
self.0.get_with_type_path(type_path).ok_or_else(|| {
make_custom_error(format_args!("no registration found for `{type_path}`"))
})
}
}
deserializer.deserialize_str(TypeRegistrationVisitor(self.registry))
}
}

View File

@@ -0,0 +1,42 @@
use crate::{
serde::{de::registration_utils::try_get_registration, TypedReflectDeserializer},
DynamicSet, Set, SetInfo, TypeRegistry,
};
use core::{fmt, fmt::Formatter};
use serde::de::{SeqAccess, Visitor};
use super::ReflectDeserializerProcessor;
/// A [`Visitor`] for deserializing [`Set`] values.
///
/// [`Set`]: crate::Set
pub(super) struct SetVisitor<'a, P> {
pub set_info: &'static SetInfo,
pub registry: &'a TypeRegistry,
pub processor: Option<&'a mut P>,
}
impl<'de, P: ReflectDeserializerProcessor> Visitor<'de> for SetVisitor<'_, P> {
type Value = DynamicSet;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("reflected set value")
}
fn visit_seq<V>(mut self, mut set: V) -> Result<Self::Value, V::Error>
where
V: SeqAccess<'de>,
{
let mut dynamic_set = DynamicSet::default();
let value_registration = try_get_registration(self.set_info.value_ty(), self.registry)?;
while let Some(value) = set.next_element_seed(TypedReflectDeserializer::new_internal(
value_registration,
self.registry,
self.processor.as_deref_mut(),
))? {
dynamic_set.insert_boxed(value);
}
Ok(dynamic_set)
}
}

View File

@@ -0,0 +1,185 @@
use crate::{
serde::{
de::{
error_utils::make_custom_error,
helpers::{ExpectedValues, Ident},
registration_utils::try_get_registration,
},
SerializationData, TypedReflectDeserializer,
},
DynamicStruct, NamedField, StructInfo, StructVariantInfo, TypeRegistration, TypeRegistry,
};
use alloc::string::ToString;
use core::slice::Iter;
use serde::de::{Error, MapAccess, SeqAccess};
use super::ReflectDeserializerProcessor;
/// A helper trait for accessing type information from struct-like types.
pub(super) trait StructLikeInfo {
fn field<E: Error>(&self, name: &str) -> Result<&NamedField, E>;
fn field_at<E: Error>(&self, index: usize) -> Result<&NamedField, E>;
fn field_len(&self) -> usize;
fn iter_fields(&self) -> Iter<'_, NamedField>;
}
impl StructLikeInfo for StructInfo {
fn field<E: Error>(&self, name: &str) -> Result<&NamedField, E> {
Self::field(self, name).ok_or_else(|| {
make_custom_error(format_args!(
"no field named `{}` on struct `{}`",
name,
self.type_path(),
))
})
}
fn field_at<E: Error>(&self, index: usize) -> Result<&NamedField, E> {
Self::field_at(self, index).ok_or_else(|| {
make_custom_error(format_args!(
"no field at index `{}` on struct `{}`",
index,
self.type_path(),
))
})
}
fn field_len(&self) -> usize {
Self::field_len(self)
}
fn iter_fields(&self) -> Iter<'_, NamedField> {
self.iter()
}
}
impl StructLikeInfo for StructVariantInfo {
fn field<E: Error>(&self, name: &str) -> Result<&NamedField, E> {
Self::field(self, name).ok_or_else(|| {
make_custom_error(format_args!(
"no field named `{}` on variant `{}`",
name,
self.name(),
))
})
}
fn field_at<E: Error>(&self, index: usize) -> Result<&NamedField, E> {
Self::field_at(self, index).ok_or_else(|| {
make_custom_error(format_args!(
"no field at index `{}` on variant `{}`",
index,
self.name(),
))
})
}
fn field_len(&self) -> usize {
Self::field_len(self)
}
fn iter_fields(&self) -> Iter<'_, NamedField> {
self.iter()
}
}
/// Deserializes a [struct-like] type from a mapping of fields, returning a [`DynamicStruct`].
///
/// [struct-like]: StructLikeInfo
pub(super) fn visit_struct<'de, T, V, P>(
map: &mut V,
info: &'static T,
registration: &TypeRegistration,
registry: &TypeRegistry,
mut processor: Option<&mut P>,
) -> Result<DynamicStruct, V::Error>
where
T: StructLikeInfo,
V: MapAccess<'de>,
P: ReflectDeserializerProcessor,
{
let mut dynamic_struct = DynamicStruct::default();
while let Some(Ident(key)) = map.next_key::<Ident>()? {
let field = info.field::<V::Error>(&key).map_err(|_| {
let fields = info.iter_fields().map(NamedField::name);
make_custom_error(format_args!(
"unknown field `{}`, expected one of {:?}",
key,
ExpectedValues::from_iter(fields)
))
})?;
let registration = try_get_registration(*field.ty(), registry)?;
let value = map.next_value_seed(TypedReflectDeserializer::new_internal(
registration,
registry,
processor.as_deref_mut(),
))?;
dynamic_struct.insert_boxed(&key, value);
}
if let Some(serialization_data) = registration.data::<SerializationData>() {
for (skipped_index, skipped_field) in serialization_data.iter_skipped() {
let Ok(field) = info.field_at::<V::Error>(*skipped_index) else {
continue;
};
dynamic_struct.insert_boxed(
field.name(),
skipped_field.generate_default().into_partial_reflect(),
);
}
}
Ok(dynamic_struct)
}
/// Deserializes a [struct-like] type from a sequence of fields, returning a [`DynamicStruct`].
///
/// [struct-like]: StructLikeInfo
pub(super) fn visit_struct_seq<'de, T, V, P>(
seq: &mut V,
info: &T,
registration: &TypeRegistration,
registry: &TypeRegistry,
mut processor: Option<&mut P>,
) -> Result<DynamicStruct, V::Error>
where
T: StructLikeInfo,
V: SeqAccess<'de>,
P: ReflectDeserializerProcessor,
{
let mut dynamic_struct = DynamicStruct::default();
let len = info.field_len();
if len == 0 {
// Handle unit structs
return Ok(dynamic_struct);
}
let serialization_data = registration.data::<SerializationData>();
for index in 0..len {
let name = info.field_at::<V::Error>(index)?.name();
if serialization_data
.map(|data| data.is_field_skipped(index))
.unwrap_or_default()
{
if let Some(value) = serialization_data.unwrap().generate_default(index) {
dynamic_struct.insert_boxed(name, value.into_partial_reflect());
}
continue;
}
let value = seq
.next_element_seed(TypedReflectDeserializer::new_internal(
try_get_registration(*info.field_at(index)?.ty(), registry)?,
registry,
processor.as_deref_mut(),
))?
.ok_or_else(|| Error::invalid_length(index, &len.to_string().as_str()))?;
dynamic_struct.insert_boxed(name, value);
}
Ok(dynamic_struct)
}

View File

@@ -0,0 +1,52 @@
use crate::{
serde::de::struct_utils::{visit_struct, visit_struct_seq},
DynamicStruct, StructInfo, TypeRegistration, TypeRegistry,
};
use core::{fmt, fmt::Formatter};
use serde::de::{MapAccess, SeqAccess, Visitor};
use super::ReflectDeserializerProcessor;
/// A [`Visitor`] for deserializing [`Struct`] values.
///
/// [`Struct`]: crate::Struct
pub(super) struct StructVisitor<'a, P> {
pub struct_info: &'static StructInfo,
pub registration: &'a TypeRegistration,
pub registry: &'a TypeRegistry,
pub processor: Option<&'a mut P>,
}
impl<'de, P: ReflectDeserializerProcessor> Visitor<'de> for StructVisitor<'_, P> {
type Value = DynamicStruct;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("reflected struct value")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
visit_struct_seq(
&mut seq,
self.struct_info,
self.registration,
self.registry,
self.processor,
)
}
fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error>
where
V: MapAccess<'de>,
{
visit_struct(
&mut map,
self.struct_info,
self.registration,
self.registry,
self.processor,
)
}
}

View File

@@ -0,0 +1,71 @@
use crate::{
serde::{de::tuple_utils::visit_tuple, SerializationData},
DynamicTupleStruct, TupleStructInfo, TypeRegistration, TypeRegistry,
};
use core::{fmt, fmt::Formatter};
use serde::de::{DeserializeSeed, SeqAccess, Visitor};
use super::{registration_utils::try_get_registration, TypedReflectDeserializer};
use super::ReflectDeserializerProcessor;
/// A [`Visitor`] for deserializing [`TupleStruct`] values.
///
/// [`TupleStruct`]: crate::TupleStruct
pub(super) struct TupleStructVisitor<'a, P> {
pub tuple_struct_info: &'static TupleStructInfo,
pub registration: &'a TypeRegistration,
pub registry: &'a TypeRegistry,
pub processor: Option<&'a mut P>,
}
impl<'de, P: ReflectDeserializerProcessor> Visitor<'de> for TupleStructVisitor<'_, P> {
type Value = DynamicTupleStruct;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("reflected tuple struct value")
}
fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
where
V: SeqAccess<'de>,
{
visit_tuple(
&mut seq,
self.tuple_struct_info,
self.registration,
self.registry,
self.processor,
)
.map(DynamicTupleStruct::from)
}
fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>,
{
let mut tuple = DynamicTupleStruct::default();
let serialization_data = self.registration.data::<SerializationData>();
if let Some(value) = serialization_data.and_then(|data| data.generate_default(0)) {
tuple.insert_boxed(value.into_partial_reflect());
return Ok(tuple);
}
let registration = try_get_registration(
*self
.tuple_struct_info
.field_at(0)
.ok_or(serde::de::Error::custom("Field at index 0 not found"))?
.ty(),
self.registry,
)?;
let reflect_deserializer =
TypedReflectDeserializer::new_internal(registration, self.registry, self.processor);
let value = reflect_deserializer.deserialize(deserializer)?;
tuple.insert_boxed(value.into_partial_reflect());
Ok(tuple)
}
}

View File

@@ -0,0 +1,110 @@
use crate::{
serde::{
de::{error_utils::make_custom_error, registration_utils::try_get_registration},
SerializationData, TypedReflectDeserializer,
},
DynamicTuple, TupleInfo, TupleStructInfo, TupleVariantInfo, TypeRegistration, TypeRegistry,
UnnamedField,
};
use alloc::string::ToString;
use serde::de::{Error, SeqAccess};
use super::ReflectDeserializerProcessor;
pub(super) trait TupleLikeInfo {
fn field_at<E: Error>(&self, index: usize) -> Result<&UnnamedField, E>;
fn field_len(&self) -> usize;
}
impl TupleLikeInfo for TupleInfo {
fn field_len(&self) -> usize {
Self::field_len(self)
}
fn field_at<E: Error>(&self, index: usize) -> Result<&UnnamedField, E> {
Self::field_at(self, index).ok_or_else(|| {
make_custom_error(format_args!(
"no field at index `{}` on tuple `{}`",
index,
self.type_path(),
))
})
}
}
impl TupleLikeInfo for TupleStructInfo {
fn field_len(&self) -> usize {
Self::field_len(self)
}
fn field_at<E: Error>(&self, index: usize) -> Result<&UnnamedField, E> {
Self::field_at(self, index).ok_or_else(|| {
make_custom_error(format_args!(
"no field at index `{}` on tuple struct `{}`",
index,
self.type_path(),
))
})
}
}
impl TupleLikeInfo for TupleVariantInfo {
fn field_len(&self) -> usize {
Self::field_len(self)
}
fn field_at<E: Error>(&self, index: usize) -> Result<&UnnamedField, E> {
Self::field_at(self, index).ok_or_else(|| {
make_custom_error(format_args!(
"no field at index `{}` on tuple variant `{}`",
index,
self.name(),
))
})
}
}
/// Deserializes a [tuple-like] type from a sequence of elements, returning a [`DynamicTuple`].
///
/// [tuple-like]: TupleLikeInfo
pub(super) fn visit_tuple<'de, T, V, P>(
seq: &mut V,
info: &T,
registration: &TypeRegistration,
registry: &TypeRegistry,
mut processor: Option<&mut P>,
) -> Result<DynamicTuple, V::Error>
where
T: TupleLikeInfo,
V: SeqAccess<'de>,
P: ReflectDeserializerProcessor,
{
let mut tuple = DynamicTuple::default();
let len = info.field_len();
if len == 0 {
// Handle empty tuple/tuple struct
return Ok(tuple);
}
let serialization_data = registration.data::<SerializationData>();
for index in 0..len {
if let Some(value) = serialization_data.and_then(|data| data.generate_default(index)) {
tuple.insert_boxed(value.into_partial_reflect());
continue;
}
let value = seq
.next_element_seed(TypedReflectDeserializer::new_internal(
try_get_registration(*info.field_at(index)?.ty(), registry)?,
registry,
processor.as_deref_mut(),
))?
.ok_or_else(|| Error::invalid_length(index, &len.to_string().as_str()))?;
tuple.insert_boxed(value);
}
Ok(tuple)
}

View File

@@ -0,0 +1,38 @@
use crate::{
serde::de::tuple_utils::visit_tuple, DynamicTuple, TupleInfo, TypeRegistration, TypeRegistry,
};
use core::{fmt, fmt::Formatter};
use serde::de::{SeqAccess, Visitor};
use super::ReflectDeserializerProcessor;
/// A [`Visitor`] for deserializing [`Tuple`] values.
///
/// [`Tuple`]: crate::Tuple
pub(super) struct TupleVisitor<'a, P> {
pub tuple_info: &'static TupleInfo,
pub registration: &'a TypeRegistration,
pub registry: &'a TypeRegistry,
pub processor: Option<&'a mut P>,
}
impl<'de, P: ReflectDeserializerProcessor> Visitor<'de> for TupleVisitor<'_, P> {
type Value = DynamicTuple;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("reflected tuple value")
}
fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
where
V: SeqAccess<'de>,
{
visit_tuple(
&mut seq,
self.tuple_info,
self.registration,
self.registry,
self.processor,
)
}
}

476
vendor/bevy_reflect/src/serde/mod.rs vendored Normal file
View File

@@ -0,0 +1,476 @@
mod de;
mod ser;
mod type_data;
pub use de::*;
pub use ser::*;
pub use type_data::*;
#[cfg(test)]
mod tests {
use super::*;
use crate::{
type_registry::TypeRegistry, DynamicStruct, DynamicTupleStruct, FromReflect,
PartialReflect, Reflect, Struct,
};
use serde::de::DeserializeSeed;
#[test]
fn test_serialization_struct() {
#[derive(Debug, Reflect, PartialEq)]
#[reflect(PartialEq)]
struct TestStruct {
a: i32,
#[reflect(ignore)]
b: i32,
#[reflect(skip_serializing)]
c: i32,
#[reflect(skip_serializing)]
#[reflect(default = "custom_default")]
d: i32,
e: i32,
}
fn custom_default() -> i32 {
-1
}
let mut registry = TypeRegistry::default();
registry.register::<TestStruct>();
let test_struct = TestStruct {
a: 3,
b: 4,
c: 5,
d: 6,
e: 7,
};
let serializer = ReflectSerializer::new(&test_struct, &registry);
let serialized =
ron::ser::to_string_pretty(&serializer, ron::ser::PrettyConfig::default()).unwrap();
let mut deserializer = ron::de::Deserializer::from_str(&serialized).unwrap();
let reflect_deserializer = ReflectDeserializer::new(&registry);
let deserialized = reflect_deserializer.deserialize(&mut deserializer).unwrap();
let mut expected = DynamicStruct::default();
expected.insert("a", 3);
// Ignored: expected.insert("b", 0);
expected.insert("c", 0);
expected.insert("d", -1);
expected.insert("e", 7);
assert!(
expected
.reflect_partial_eq(deserialized.as_partial_reflect())
.unwrap(),
"Deserialization failed: expected {expected:?} found {deserialized:?}"
);
let expected = TestStruct {
a: 3,
b: 0,
c: 0,
d: -1,
e: 7,
};
let received =
<TestStruct as FromReflect>::from_reflect(deserialized.as_partial_reflect()).unwrap();
assert_eq!(
expected, received,
"FromReflect failed: expected {expected:?} found {received:?}"
);
}
#[test]
fn test_serialization_tuple_struct() {
#[derive(Debug, Reflect, PartialEq)]
#[reflect(PartialEq)]
struct TestStruct(
i32,
#[reflect(ignore)] i32,
#[reflect(skip_serializing)] i32,
#[reflect(skip_serializing)]
#[reflect(default = "custom_default")]
i32,
i32,
);
fn custom_default() -> i32 {
-1
}
let mut registry = TypeRegistry::default();
registry.register::<TestStruct>();
let test_struct = TestStruct(3, 4, 5, 6, 7);
let serializer = ReflectSerializer::new(&test_struct, &registry);
let serialized =
ron::ser::to_string_pretty(&serializer, ron::ser::PrettyConfig::default()).unwrap();
let mut deserializer = ron::de::Deserializer::from_str(&serialized).unwrap();
let reflect_deserializer = ReflectDeserializer::new(&registry);
let deserialized = reflect_deserializer.deserialize(&mut deserializer).unwrap();
let mut expected = DynamicTupleStruct::default();
expected.insert(3);
// Ignored: expected.insert(0);
expected.insert(0);
expected.insert(-1);
expected.insert(7);
assert!(
expected
.reflect_partial_eq(deserialized.as_partial_reflect())
.unwrap(),
"Deserialization failed: expected {expected:?} found {deserialized:?}"
);
let expected = TestStruct(3, 0, 0, -1, 7);
let received =
<TestStruct as FromReflect>::from_reflect(deserialized.as_partial_reflect()).unwrap();
assert_eq!(
expected, received,
"FromReflect failed: expected {expected:?} found {received:?}"
);
}
#[test]
#[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();
value.insert("foo", 123_u32);
let serializer = ReflectSerializer::new(&value, &registry);
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 }.to_dynamic_struct();
let serializer = ReflectSerializer::new(&value, &registry);
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 = ReflectDeserializer::new(&registry);
let expected = value.to_dynamic();
let result = reflect_deserializer.deserialize(&mut deserializer).unwrap();
assert!(expected
.reflect_partial_eq(result.as_partial_reflect())
.unwrap());
}
mod type_data {
use super::*;
use crate::from_reflect::FromReflect;
use crate::serde::{DeserializeWithRegistry, ReflectDeserializeWithRegistry};
use crate::serde::{ReflectSerializeWithRegistry, SerializeWithRegistry};
use crate::{ReflectFromReflect, TypePath};
use alloc::{format, string::String, vec, vec::Vec};
use bevy_platform::sync::Arc;
use bevy_reflect_derive::reflect_trait;
use core::any::TypeId;
use core::fmt::{Debug, Formatter};
use serde::de::{SeqAccess, Visitor};
use serde::ser::SerializeSeq;
use serde::{Deserializer, Serialize, Serializer};
#[reflect_trait]
trait Enemy: Reflect + Debug {
#[expect(dead_code, reason = "this method is purely for testing purposes")]
fn hp(&self) -> u8;
}
// This is needed to support Arc<dyn Enemy>
impl TypePath for dyn Enemy {
fn type_path() -> &'static str {
"dyn bevy_reflect::serde::tests::type_data::Enemy"
}
fn short_type_path() -> &'static str {
"dyn Enemy"
}
}
#[derive(Reflect, Debug)]
#[reflect(Enemy)]
struct Skeleton(u8);
impl Enemy for Skeleton {
fn hp(&self) -> u8 {
self.0
}
}
#[derive(Reflect, Debug)]
#[reflect(Enemy)]
struct Zombie {
health: u8,
walk_speed: f32,
}
impl Enemy for Zombie {
fn hp(&self) -> u8 {
self.health
}
}
#[derive(Reflect, Debug)]
struct Level {
name: String,
enemies: EnemyList,
}
#[derive(Reflect, Debug)]
#[reflect(SerializeWithRegistry, DeserializeWithRegistry)]
// Note that we have to use `Arc` instead of `Box` here due to the
// former being the only one between the two to implement `Reflect`.
struct EnemyList(Vec<Arc<dyn Enemy>>);
impl SerializeWithRegistry for EnemyList {
fn serialize<S>(
&self,
serializer: S,
registry: &TypeRegistry,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut state = serializer.serialize_seq(Some(self.0.len()))?;
for enemy in &self.0 {
state.serialize_element(&ReflectSerializer::new(
(**enemy).as_partial_reflect(),
registry,
))?;
}
state.end()
}
}
impl<'de> DeserializeWithRegistry<'de> for EnemyList {
fn deserialize<D>(deserializer: D, registry: &TypeRegistry) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct EnemyListVisitor<'a> {
registry: &'a TypeRegistry,
}
impl<'a, 'de> Visitor<'de> for EnemyListVisitor<'a> {
type Value = Vec<Arc<dyn Enemy>>;
fn expecting(&self, formatter: &mut Formatter) -> core::fmt::Result {
write!(formatter, "a list of enemies")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut enemies = Vec::new();
while let Some(enemy) =
seq.next_element_seed(ReflectDeserializer::new(self.registry))?
{
let registration = self
.registry
.get_with_type_path(
enemy.get_represented_type_info().unwrap().type_path(),
)
.unwrap();
// 1. Convert any possible dynamic values to concrete ones
let enemy = registration
.data::<ReflectFromReflect>()
.unwrap()
.from_reflect(&*enemy)
.unwrap();
// 2. Convert the concrete value to a boxed trait object
let enemy = registration
.data::<ReflectEnemy>()
.unwrap()
.get_boxed(enemy)
.unwrap();
enemies.push(enemy.into());
}
Ok(enemies)
}
}
deserializer
.deserialize_seq(EnemyListVisitor { registry })
.map(EnemyList)
}
}
fn create_registry() -> TypeRegistry {
let mut registry = TypeRegistry::default();
registry.register::<Level>();
registry.register::<EnemyList>();
registry.register::<Skeleton>();
registry.register::<Zombie>();
registry
}
fn create_arc_dyn_enemy<T: Enemy>(enemy: T) -> Arc<dyn Enemy> {
let arc = Arc::new(enemy);
#[cfg(not(target_has_atomic = "ptr"))]
#[expect(
unsafe_code,
reason = "unsized coercion is an unstable feature for non-std types"
)]
// SAFETY:
// - Coercion from `T` to `dyn Enemy` is valid as `T: Enemy + 'static`
// - `Arc::from_raw` receives a valid pointer from a previous call to `Arc::into_raw`
let arc = unsafe { Arc::from_raw(Arc::into_raw(arc) as *const dyn Enemy) };
arc
}
#[test]
fn should_serialize_with_serialize_with_registry() {
let registry = create_registry();
let level = Level {
name: String::from("Level 1"),
enemies: EnemyList(vec![
create_arc_dyn_enemy(Skeleton(10)),
create_arc_dyn_enemy(Zombie {
health: 20,
walk_speed: 0.5,
}),
]),
};
let serializer = ReflectSerializer::new(&level, &registry);
let serialized = ron::ser::to_string(&serializer).unwrap();
let expected = r#"{"bevy_reflect::serde::tests::type_data::Level":(name:"Level 1",enemies:[{"bevy_reflect::serde::tests::type_data::Skeleton":(10)},{"bevy_reflect::serde::tests::type_data::Zombie":(health:20,walk_speed:0.5)}])}"#;
assert_eq!(expected, serialized);
}
#[test]
fn should_deserialize_with_deserialize_with_registry() {
let registry = create_registry();
let input = r#"{"bevy_reflect::serde::tests::type_data::Level":(name:"Level 1",enemies:[{"bevy_reflect::serde::tests::type_data::Skeleton":(10)},{"bevy_reflect::serde::tests::type_data::Zombie":(health:20,walk_speed:0.5)}])}"#;
let mut deserializer = ron::de::Deserializer::from_str(input).unwrap();
let reflect_deserializer = ReflectDeserializer::new(&registry);
let value = reflect_deserializer.deserialize(&mut deserializer).unwrap();
let output = Level::from_reflect(&*value).unwrap();
let expected = Level {
name: String::from("Level 1"),
enemies: EnemyList(vec![
create_arc_dyn_enemy(Skeleton(10)),
create_arc_dyn_enemy(Zombie {
health: 20,
walk_speed: 0.5,
}),
]),
};
// Poor man's comparison since we can't derive PartialEq for Arc<dyn Enemy>
assert_eq!(format!("{:?}", expected), format!("{:?}", output));
let unexpected = Level {
name: String::from("Level 1"),
enemies: EnemyList(vec![
create_arc_dyn_enemy(Skeleton(20)),
create_arc_dyn_enemy(Zombie {
health: 20,
walk_speed: 5.0,
}),
]),
};
// Poor man's comparison since we can't derive PartialEq for Arc<dyn Enemy>
assert_ne!(format!("{:?}", unexpected), format!("{:?}", output));
}
#[test]
fn should_serialize_single_tuple_struct_as_newtype() {
#[derive(Reflect, Serialize, PartialEq, Debug)]
struct TupleStruct(u32);
#[derive(Reflect, Serialize, PartialEq, Debug)]
struct TupleStructWithSkip(
u32,
#[reflect(skip_serializing)]
#[serde(skip)]
u32,
);
#[derive(Reflect, Serialize, PartialEq, Debug)]
enum Enum {
TupleStruct(usize),
NestedTupleStruct(TupleStruct),
NestedTupleStructWithSkip(TupleStructWithSkip),
}
let mut registry = TypeRegistry::default();
registry.register::<TupleStruct>();
registry.register::<TupleStructWithSkip>();
registry.register::<Enum>();
let tuple_struct = TupleStruct(1);
let tuple_struct_with_skip = TupleStructWithSkip(2, 3);
let tuple_struct_enum = Enum::TupleStruct(4);
let nested_tuple_struct = Enum::NestedTupleStruct(TupleStruct(5));
let nested_tuple_struct_with_skip =
Enum::NestedTupleStructWithSkip(TupleStructWithSkip(6, 7));
fn assert_serialize<T: Reflect + FromReflect + Serialize + PartialEq + Debug>(
value: &T,
registry: &TypeRegistry,
) {
let serializer = TypedReflectSerializer::new(value, registry);
let reflect_serialize = serde_json::to_string(&serializer).unwrap();
let serde_serialize = serde_json::to_string(value).unwrap();
assert_eq!(reflect_serialize, serde_serialize);
let registration = registry.get(TypeId::of::<T>()).unwrap();
let reflect_deserializer = TypedReflectDeserializer::new(registration, registry);
let mut deserializer = serde_json::Deserializer::from_str(&serde_serialize);
let reflect_value = reflect_deserializer.deserialize(&mut deserializer).unwrap();
let _ = T::from_reflect(&*reflect_value).unwrap();
}
assert_serialize(&tuple_struct, &registry);
assert_serialize(&tuple_struct_with_skip, &registry);
assert_serialize(&tuple_struct_enum, &registry);
assert_serialize(&nested_tuple_struct, &registry);
assert_serialize(&nested_tuple_struct_with_skip, &registry);
}
}
}

View File

@@ -0,0 +1,28 @@
use crate::{serde::TypedReflectSerializer, Array, TypeRegistry};
use serde::{ser::SerializeTuple, Serialize};
use super::ReflectSerializerProcessor;
/// A serializer for [`Array`] values.
pub(super) struct ArraySerializer<'a, P> {
pub array: &'a dyn Array,
pub registry: &'a TypeRegistry,
pub processor: Option<&'a P>,
}
impl<P: ReflectSerializerProcessor> Serialize for ArraySerializer<'_, P> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut state = serializer.serialize_tuple(self.array.len())?;
for value in self.array.iter() {
state.serialize_element(&TypedReflectSerializer::new_internal(
value,
self.registry,
self.processor,
))?;
}
state.end()
}
}

View File

@@ -0,0 +1,62 @@
use crate::serde::ser::error_utils::make_custom_error;
#[cfg(feature = "debug_stack")]
use crate::serde::ser::error_utils::TYPE_INFO_STACK;
use crate::serde::ReflectSerializeWithRegistry;
use crate::{PartialReflect, ReflectSerialize, TypeRegistry};
use core::borrow::Borrow;
use serde::{Serialize, Serializer};
/// Attempts to serialize a [`PartialReflect`] value with custom [`ReflectSerialize`]
/// or [`ReflectSerializeWithRegistry`] type data.
///
/// On success, returns the result of the serialization.
/// On failure, returns the original serializer and the error that occurred.
pub(super) fn try_custom_serialize<S: Serializer>(
value: &dyn PartialReflect,
type_registry: &TypeRegistry,
serializer: S,
) -> Result<Result<S::Ok, S::Error>, (S, S::Error)> {
let Some(value) = value.try_as_reflect() else {
return Err((
serializer,
make_custom_error(format_args!(
"type `{}` does not implement `Reflect`",
value.reflect_type_path()
)),
));
};
let info = value.reflect_type_info();
let Some(registration) = type_registry.get(info.type_id()) else {
return Err((
serializer,
make_custom_error(format_args!(
"type `{}` is not registered in the type registry",
info.type_path(),
)),
));
};
if let Some(reflect_serialize) = registration.data::<ReflectSerialize>() {
#[cfg(feature = "debug_stack")]
TYPE_INFO_STACK.with_borrow_mut(crate::type_info_stack::TypeInfoStack::pop);
Ok(reflect_serialize
.get_serializable(value)
.borrow()
.serialize(serializer))
} else if let Some(reflect_serialize_with_registry) =
registration.data::<ReflectSerializeWithRegistry>()
{
#[cfg(feature = "debug_stack")]
TYPE_INFO_STACK.with_borrow_mut(crate::type_info_stack::TypeInfoStack::pop);
Ok(reflect_serialize_with_registry.serialize(value, serializer, type_registry))
} else {
Err((serializer, make_custom_error(format_args!(
"type `{}` did not register the `ReflectSerialize` or `ReflectSerializeWithRegistry` type data. For certain types, this may need to be registered manually using `register_type_data`",
info.type_path(),
))))
}
}

View File

@@ -0,0 +1,130 @@
use crate::{
serde::{ser::error_utils::make_custom_error, TypedReflectSerializer},
Enum, TypeInfo, TypeRegistry, VariantInfo, VariantType,
};
use serde::{
ser::{SerializeStructVariant, SerializeTupleVariant},
Serialize,
};
use super::ReflectSerializerProcessor;
/// A serializer for [`Enum`] values.
pub(super) struct EnumSerializer<'a, P> {
pub enum_value: &'a dyn Enum,
pub registry: &'a TypeRegistry,
pub processor: Option<&'a P>,
}
impl<P: ReflectSerializerProcessor> Serialize for EnumSerializer<'_, P> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let type_info = self.enum_value.get_represented_type_info().ok_or_else(|| {
make_custom_error(format_args!(
"cannot get type info for `{}`",
self.enum_value.reflect_type_path()
))
})?;
let enum_info = match type_info {
TypeInfo::Enum(enum_info) => enum_info,
info => {
return Err(make_custom_error(format_args!(
"expected enum type but received {info:?}"
)));
}
};
let enum_name = enum_info.type_path_table().ident().unwrap();
let variant_index = self.enum_value.variant_index() as u32;
let variant_info = enum_info
.variant_at(variant_index as usize)
.ok_or_else(|| {
make_custom_error(format_args!(
"variant at index `{variant_index}` does not exist",
))
})?;
let variant_name = variant_info.name();
let variant_type = self.enum_value.variant_type();
let field_len = self.enum_value.field_len();
match variant_type {
VariantType::Unit => {
if type_info.type_path_table().module_path() == Some("core::option")
&& type_info.type_path_table().ident() == Some("Option")
{
serializer.serialize_none()
} else {
serializer.serialize_unit_variant(enum_name, variant_index, variant_name)
}
}
VariantType::Struct => {
let struct_info = match variant_info {
VariantInfo::Struct(struct_info) => struct_info,
info => {
return Err(make_custom_error(format_args!(
"expected struct variant type but received {info:?}",
)));
}
};
let mut state = serializer.serialize_struct_variant(
enum_name,
variant_index,
variant_name,
field_len,
)?;
for (index, field) in self.enum_value.iter_fields().enumerate() {
let field_info = struct_info.field_at(index).unwrap();
state.serialize_field(
field_info.name(),
&TypedReflectSerializer::new_internal(
field.value(),
self.registry,
self.processor,
),
)?;
}
state.end()
}
VariantType::Tuple if field_len == 1 => {
let field = self.enum_value.field_at(0).unwrap();
if type_info.type_path_table().module_path() == Some("core::option")
&& type_info.type_path_table().ident() == Some("Option")
{
serializer.serialize_some(&TypedReflectSerializer::new_internal(
field,
self.registry,
self.processor,
))
} else {
serializer.serialize_newtype_variant(
enum_name,
variant_index,
variant_name,
&TypedReflectSerializer::new_internal(field, self.registry, self.processor),
)
}
}
VariantType::Tuple => {
let mut state = serializer.serialize_tuple_variant(
enum_name,
variant_index,
variant_name,
field_len,
)?;
for field in self.enum_value.iter_fields() {
state.serialize_field(&TypedReflectSerializer::new_internal(
field.value(),
self.registry,
self.processor,
))?;
}
state.end()
}
}
}
}

View File

@@ -0,0 +1,29 @@
use core::fmt::Display;
use serde::ser::Error;
#[cfg(feature = "debug_stack")]
use std::thread_local;
#[cfg(feature = "debug_stack")]
thread_local! {
/// The thread-local [`TypeInfoStack`] used for debugging.
///
/// [`TypeInfoStack`]: crate::type_info_stack::TypeInfoStack
pub(super) static TYPE_INFO_STACK: core::cell::RefCell<crate::type_info_stack::TypeInfoStack> = const { core::cell::RefCell::new(
crate::type_info_stack::TypeInfoStack::new()
) };
}
/// A helper function for generating a custom serialization error message.
///
/// This function should be preferred over [`Error::custom`] as it will include
/// other useful information, such as the [type info stack].
///
/// [type info stack]: crate::type_info_stack::TypeInfoStack
pub(super) fn make_custom_error<E: Error>(msg: impl Display) -> E {
#[cfg(feature = "debug_stack")]
return TYPE_INFO_STACK
.with_borrow(|stack| E::custom(format_args!("{} (stack: {:?})", msg, stack)));
#[cfg(not(feature = "debug_stack"))]
return E::custom(msg);
}

View File

@@ -0,0 +1,28 @@
use crate::{serde::TypedReflectSerializer, List, TypeRegistry};
use serde::{ser::SerializeSeq, Serialize};
use super::ReflectSerializerProcessor;
/// A serializer for [`List`] values.
pub(super) struct ListSerializer<'a, P> {
pub list: &'a dyn List,
pub registry: &'a TypeRegistry,
pub processor: Option<&'a P>,
}
impl<P: ReflectSerializerProcessor> Serialize for ListSerializer<'_, P> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut state = serializer.serialize_seq(Some(self.list.len()))?;
for value in self.list.iter() {
state.serialize_element(&TypedReflectSerializer::new_internal(
value,
self.registry,
self.processor,
))?;
}
state.end()
}
}

View File

@@ -0,0 +1,27 @@
use crate::{serde::TypedReflectSerializer, Map, TypeRegistry};
use serde::{ser::SerializeMap, Serialize};
use super::ReflectSerializerProcessor;
/// A serializer for [`Map`] values.
pub(super) struct MapSerializer<'a, P> {
pub map: &'a dyn Map,
pub registry: &'a TypeRegistry,
pub processor: Option<&'a P>,
}
impl<P: ReflectSerializerProcessor> Serialize for MapSerializer<'_, P> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut state = serializer.serialize_map(Some(self.map.len()))?;
for (key, value) in self.map.iter() {
state.serialize_entry(
&TypedReflectSerializer::new_internal(key, self.registry, self.processor),
&TypedReflectSerializer::new_internal(value, self.registry, self.processor),
)?;
}
state.end()
}
}

733
vendor/bevy_reflect/src/serde/ser/mod.rs vendored Normal file
View File

@@ -0,0 +1,733 @@
pub use processor::*;
pub use serializable::*;
pub use serialize_with_registry::*;
pub use serializer::*;
mod arrays;
mod custom_serialization;
mod enums;
mod error_utils;
mod lists;
mod maps;
mod processor;
mod serializable;
mod serialize_with_registry;
mod serializer;
mod sets;
mod structs;
mod tuple_structs;
mod tuples;
#[cfg(test)]
mod tests {
use crate::{
serde::{ReflectSerializer, ReflectSerializerProcessor},
PartialReflect, Reflect, ReflectSerialize, Struct, TypeRegistry,
};
#[cfg(feature = "functions")]
use alloc::boxed::Box;
use alloc::{
string::{String, ToString},
vec,
vec::Vec,
};
use bevy_platform::collections::{HashMap, HashSet};
use core::{any::TypeId, f32::consts::PI, ops::RangeInclusive};
use ron::{extensions::Extensions, ser::PrettyConfig};
use serde::{Serialize, Serializer};
#[derive(Reflect, Debug, PartialEq)]
struct MyStruct {
primitive_value: i8,
option_value: Option<String>,
option_value_complex: Option<SomeStruct>,
tuple_value: (f32, usize),
list_value: Vec<i32>,
array_value: [i32; 5],
map_value: HashMap<u8, usize>,
set_value: HashSet<u8>,
struct_value: SomeStruct,
tuple_struct_value: SomeTupleStruct,
unit_struct: SomeUnitStruct,
unit_enum: SomeEnum,
newtype_enum: SomeEnum,
tuple_enum: SomeEnum,
struct_enum: SomeEnum,
ignored_struct: SomeIgnoredStruct,
ignored_tuple_struct: SomeIgnoredTupleStruct,
ignored_struct_variant: SomeIgnoredEnum,
ignored_tuple_variant: SomeIgnoredEnum,
custom_serialize: CustomSerialize,
}
#[derive(Reflect, Debug, PartialEq)]
struct SomeStruct {
foo: i64,
}
#[derive(Reflect, Debug, PartialEq)]
struct SomeTupleStruct(String);
#[derive(Reflect, Debug, PartialEq)]
struct SomeUnitStruct;
#[derive(Reflect, Debug, PartialEq)]
struct SomeIgnoredStruct {
#[reflect(ignore)]
ignored: i32,
}
#[derive(Reflect, Debug, PartialEq)]
struct SomeIgnoredTupleStruct(#[reflect(ignore)] i32);
#[derive(Reflect, Debug, PartialEq)]
enum SomeEnum {
Unit,
NewType(usize),
Tuple(f32, f32),
Struct { foo: String },
}
#[derive(Reflect, Debug, PartialEq)]
enum SomeIgnoredEnum {
Tuple(#[reflect(ignore)] f32, #[reflect(ignore)] f32),
Struct {
#[reflect(ignore)]
foo: String,
},
}
#[derive(Reflect, Debug, PartialEq, Serialize)]
struct SomeSerializableStruct {
foo: i64,
}
/// Implements a custom serialize using `#[reflect(Serialize)]`.
///
/// For testing purposes, this just uses the generated one from deriving Serialize.
#[derive(Reflect, Debug, PartialEq, Serialize)]
#[reflect(Serialize)]
struct CustomSerialize {
value: usize,
#[serde(rename = "renamed")]
inner_struct: SomeSerializableStruct,
}
fn get_registry() -> TypeRegistry {
let mut registry = TypeRegistry::default();
registry.register::<MyStruct>();
registry.register::<SomeStruct>();
registry.register::<SomeTupleStruct>();
registry.register::<SomeUnitStruct>();
registry.register::<SomeIgnoredStruct>();
registry.register::<SomeIgnoredTupleStruct>();
registry.register::<SomeIgnoredEnum>();
registry.register::<CustomSerialize>();
registry.register::<SomeEnum>();
registry.register::<SomeSerializableStruct>();
registry.register_type_data::<SomeSerializableStruct, ReflectSerialize>();
registry.register::<String>();
registry.register::<Option<String>>();
registry.register_type_data::<Option<String>, ReflectSerialize>();
registry
}
fn get_my_struct() -> MyStruct {
let mut map = <HashMap<_, _>>::default();
map.insert(64, 32);
let mut set = <HashSet<_>>::default();
set.insert(64);
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,
set_value: set,
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 },
},
}
}
#[test]
fn should_serialize() {
let input = get_my_struct();
let registry = get_registry();
let serializer = ReflectSerializer::new(&input, &registry);
let config = PrettyConfig::default()
.new_line(String::from("\n"))
.indentor(String::from(" "));
let output = ron::ser::to_string_pretty(&serializer, config).unwrap();
let expected = r#"{
"bevy_reflect::serde::ser::tests::MyStruct": (
primitive_value: 123,
option_value: Some("Hello world!"),
option_value_complex: Some((
foo: 123,
)),
tuple_value: (3.1415927, 1337),
list_value: [
-2,
-1,
0,
1,
2,
],
array_value: (-2, -1, 0, 1, 2),
map_value: {
64: 32,
},
set_value: [
64,
],
struct_value: (
foo: 999999999,
),
tuple_struct_value: ("Tuple Struct"),
unit_struct: (),
unit_enum: Unit,
newtype_enum: NewType(123),
tuple_enum: Tuple(1.23, 3.21),
struct_enum: Struct(
foo: "Struct variant value",
),
ignored_struct: (),
ignored_tuple_struct: (),
ignored_struct_variant: Struct(),
ignored_tuple_variant: Tuple(),
custom_serialize: (
value: 100,
renamed: (
foo: 101,
),
),
),
}"#;
assert_eq!(expected, output);
}
#[test]
fn should_serialize_option() {
#[derive(Reflect, Debug, PartialEq)]
struct OptionTest {
none: Option<()>,
simple: Option<String>,
complex: Option<SomeStruct>,
}
let value = OptionTest {
none: None,
simple: Some(String::from("Hello world!")),
complex: Some(SomeStruct { foo: 123 }),
};
let registry = get_registry();
let serializer = ReflectSerializer::new(&value, &registry);
// === Normal === //
let config = PrettyConfig::default()
.new_line(String::from("\n"))
.indentor(String::from(" "));
let output = ron::ser::to_string_pretty(&serializer, config).unwrap();
let expected = r#"{
"bevy_reflect::serde::ser::tests::OptionTest": (
none: None,
simple: Some("Hello world!"),
complex: Some((
foo: 123,
)),
),
}"#;
assert_eq!(expected, output);
// === Implicit Some === //
let config = PrettyConfig::default()
.new_line(String::from("\n"))
.extensions(Extensions::IMPLICIT_SOME)
.indentor(String::from(" "));
let output = ron::ser::to_string_pretty(&serializer, config).unwrap();
let expected = r#"#![enable(implicit_some)]
{
"bevy_reflect::serde::ser::tests::OptionTest": (
none: None,
simple: "Hello world!",
complex: (
foo: 123,
),
),
}"#;
assert_eq!(expected, output);
}
#[test]
fn enum_should_serialize() {
#[derive(Reflect)]
enum MyEnum {
Unit,
NewType(usize),
Tuple(f32, f32),
Struct { value: String },
}
let mut registry = get_registry();
registry.register::<MyEnum>();
let config = PrettyConfig::default().new_line(String::from("\n"));
// === Unit Variant === //
let value = MyEnum::Unit;
let serializer = ReflectSerializer::new(&value, &registry);
let output = ron::ser::to_string_pretty(&serializer, config.clone()).unwrap();
let expected = r#"{
"bevy_reflect::serde::ser::tests::MyEnum": Unit,
}"#;
assert_eq!(expected, output);
// === NewType Variant === //
let value = MyEnum::NewType(123);
let serializer = ReflectSerializer::new(&value, &registry);
let output = ron::ser::to_string_pretty(&serializer, config.clone()).unwrap();
let expected = r#"{
"bevy_reflect::serde::ser::tests::MyEnum": NewType(123),
}"#;
assert_eq!(expected, output);
// === Tuple Variant === //
let value = MyEnum::Tuple(1.23, 3.21);
let serializer = ReflectSerializer::new(&value, &registry);
let output = ron::ser::to_string_pretty(&serializer, config.clone()).unwrap();
let expected = r#"{
"bevy_reflect::serde::ser::tests::MyEnum": Tuple(1.23, 3.21),
}"#;
assert_eq!(expected, output);
// === Struct Variant === //
let value = MyEnum::Struct {
value: String::from("I <3 Enums"),
};
let serializer = ReflectSerializer::new(&value, &registry);
let output = ron::ser::to_string_pretty(&serializer, config).unwrap();
let expected = r#"{
"bevy_reflect::serde::ser::tests::MyEnum": Struct(
value: "I <3 Enums",
),
}"#;
assert_eq!(expected, output);
}
#[test]
fn should_serialize_non_self_describing_binary() {
let input = get_my_struct();
let registry = get_registry();
let serializer = ReflectSerializer::new(&input, &registry);
let config = bincode::config::standard().with_fixed_int_encoding();
let bytes = bincode::serde::encode_to_vec(&serializer, config).unwrap();
let expected: Vec<u8> = vec![
1, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 98, 101, 118, 121, 95, 114, 101, 102,
108, 101, 99, 116, 58, 58, 115, 101, 114, 100, 101, 58, 58, 115, 101, 114, 58, 58, 116,
101, 115, 116, 115, 58, 58, 77, 121, 83, 116, 114, 117, 99, 116, 123, 1, 12, 0, 0, 0,
0, 0, 0, 0, 72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33, 1, 123, 0, 0, 0,
0, 0, 0, 0, 219, 15, 73, 64, 57, 5, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 254, 255,
255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 254, 255, 255, 255,
255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 32,
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 255, 201, 154, 59, 0, 0, 0, 0, 12, 0,
0, 0, 0, 0, 0, 0, 84, 117, 112, 108, 101, 32, 83, 116, 114, 117, 99, 116, 0, 0, 0, 0,
1, 0, 0, 0, 123, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 164, 112, 157, 63, 164, 112, 77, 64,
3, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 83, 116, 114, 117, 99, 116, 32, 118, 97, 114, 105,
97, 110, 116, 32, 118, 97, 108, 117, 101, 1, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0,
0, 0, 101, 0, 0, 0, 0, 0, 0, 0,
];
assert_eq!(expected, bytes);
}
#[test]
fn should_serialize_self_describing_binary() {
let input = get_my_struct();
let registry = get_registry();
let serializer = ReflectSerializer::new(&input, &registry);
let bytes: Vec<u8> = rmp_serde::to_vec(&serializer).unwrap();
let expected: Vec<u8> = vec![
129, 217, 41, 98, 101, 118, 121, 95, 114, 101, 102, 108, 101, 99, 116, 58, 58, 115,
101, 114, 100, 101, 58, 58, 115, 101, 114, 58, 58, 116, 101, 115, 116, 115, 58, 58, 77,
121, 83, 116, 114, 117, 99, 116, 220, 0, 20, 123, 172, 72, 101, 108, 108, 111, 32, 119,
111, 114, 108, 100, 33, 145, 123, 146, 202, 64, 73, 15, 219, 205, 5, 57, 149, 254, 255,
0, 1, 2, 149, 254, 255, 0, 1, 2, 129, 64, 32, 145, 64, 145, 206, 59, 154, 201, 255,
172, 84, 117, 112, 108, 101, 32, 83, 116, 114, 117, 99, 116, 144, 164, 85, 110, 105,
116, 129, 167, 78, 101, 119, 84, 121, 112, 101, 123, 129, 165, 84, 117, 112, 108, 101,
146, 202, 63, 157, 112, 164, 202, 64, 77, 112, 164, 129, 166, 83, 116, 114, 117, 99,
116, 145, 180, 83, 116, 114, 117, 99, 116, 32, 118, 97, 114, 105, 97, 110, 116, 32,
118, 97, 108, 117, 101, 144, 144, 129, 166, 83, 116, 114, 117, 99, 116, 144, 129, 165,
84, 117, 112, 108, 101, 144, 146, 100, 145, 101,
];
assert_eq!(expected, bytes);
}
#[test]
fn should_serialize_dynamic_option() {
#[derive(Default, Reflect)]
struct OtherStruct {
some: Option<SomeStruct>,
none: Option<SomeStruct>,
}
let value = OtherStruct {
some: Some(SomeStruct { foo: 999999999 }),
none: None,
};
let dynamic = value.to_dynamic_struct();
let reflect = dynamic.as_partial_reflect();
let registry = get_registry();
let serializer = ReflectSerializer::new(reflect, &registry);
let mut buf = Vec::new();
let format = serde_json::ser::PrettyFormatter::with_indent(b" ");
let mut ser = serde_json::Serializer::with_formatter(&mut buf, format);
serializer.serialize(&mut ser).unwrap();
let output = core::str::from_utf8(&buf).unwrap();
let expected = r#"{
"bevy_reflect::serde::ser::tests::OtherStruct": {
"some": {
"foo": 999999999
},
"none": null
}
}"#;
assert_eq!(expected, output);
}
#[test]
fn should_return_error_if_missing_registration() {
let value = RangeInclusive::<f32>::new(0.0, 1.0);
let registry = TypeRegistry::new();
let serializer = ReflectSerializer::new(&value, &registry);
let error = ron::ser::to_string(&serializer).unwrap_err();
#[cfg(feature = "debug_stack")]
assert_eq!(
error,
ron::Error::Message(
"type `core::ops::RangeInclusive<f32>` is not registered in the type registry (stack: `core::ops::RangeInclusive<f32>`)"
.to_string(),
)
);
#[cfg(not(feature = "debug_stack"))]
assert_eq!(
error,
ron::Error::Message(
"type `core::ops::RangeInclusive<f32>` is not registered in the type registry"
.to_string(),
)
);
}
#[test]
fn should_return_error_if_missing_type_data() {
let value = RangeInclusive::<f32>::new(0.0, 1.0);
let mut registry = TypeRegistry::new();
registry.register::<RangeInclusive<f32>>();
let serializer = ReflectSerializer::new(&value, &registry);
let error = ron::ser::to_string(&serializer).unwrap_err();
#[cfg(feature = "debug_stack")]
assert_eq!(
error,
ron::Error::Message(
"type `core::ops::RangeInclusive<f32>` did not register the `ReflectSerialize` or `ReflectSerializeWithRegistry` type data. For certain types, this may need to be registered manually using `register_type_data` (stack: `core::ops::RangeInclusive<f32>`)".to_string()
)
);
#[cfg(not(feature = "debug_stack"))]
assert_eq!(
error,
ron::Error::Message(
"type `core::ops::RangeInclusive<f32>` did not register the `ReflectSerialize` type data. For certain types, this may need to be registered manually using `register_type_data`".to_string()
)
);
}
#[test]
fn should_use_processor_for_custom_serialization() {
#[derive(Reflect, Debug, PartialEq)]
struct Foo {
bar: i32,
qux: i64,
}
struct FooProcessor;
impl ReflectSerializerProcessor for FooProcessor {
fn try_serialize<S>(
&self,
value: &dyn PartialReflect,
_: &TypeRegistry,
serializer: S,
) -> Result<Result<S::Ok, S>, S::Error>
where
S: Serializer,
{
let Some(value) = value.try_as_reflect() else {
return Ok(Err(serializer));
};
let type_id = value.reflect_type_info().type_id();
if type_id == TypeId::of::<i64>() {
Ok(Ok(serializer.serialize_str("custom!")?))
} else {
Ok(Err(serializer))
}
}
}
let value = Foo { bar: 123, qux: 456 };
let mut registry = TypeRegistry::new();
registry.register::<Foo>();
let processor = FooProcessor;
let serializer = ReflectSerializer::with_processor(&value, &registry, &processor);
let config = PrettyConfig::default().new_line(String::from("\n"));
let output = ron::ser::to_string_pretty(&serializer, config).unwrap();
let expected = r#"{
"bevy_reflect::serde::ser::tests::Foo": (
bar: 123,
qux: "custom!",
),
}"#;
assert_eq!(expected, output);
}
#[test]
fn should_use_processor_for_multiple_registrations() {
#[derive(Reflect, Debug, PartialEq)]
struct Foo {
bar: i32,
sub: SubFoo,
}
#[derive(Reflect, Debug, PartialEq)]
struct SubFoo {
val: i32,
}
struct FooProcessor;
impl ReflectSerializerProcessor for FooProcessor {
fn try_serialize<S>(
&self,
value: &dyn PartialReflect,
_: &TypeRegistry,
serializer: S,
) -> Result<Result<S::Ok, S>, S::Error>
where
S: Serializer,
{
let Some(value) = value.try_as_reflect() else {
return Ok(Err(serializer));
};
let type_id = value.reflect_type_info().type_id();
if type_id == TypeId::of::<i32>() {
Ok(Ok(serializer.serialize_str("an i32")?))
} else if type_id == TypeId::of::<SubFoo>() {
Ok(Ok(serializer.serialize_str("a SubFoo")?))
} else {
Ok(Err(serializer))
}
}
}
let value = Foo {
bar: 123,
sub: SubFoo { val: 456 },
};
let mut registry = TypeRegistry::new();
registry.register::<Foo>();
registry.register::<SubFoo>();
let processor = FooProcessor;
let serializer = ReflectSerializer::with_processor(&value, &registry, &processor);
let config = PrettyConfig::default().new_line(String::from("\n"));
let output = ron::ser::to_string_pretty(&serializer, config).unwrap();
let expected = r#"{
"bevy_reflect::serde::ser::tests::Foo": (
bar: "an i32",
sub: "a SubFoo",
),
}"#;
assert_eq!(expected, output);
}
#[test]
fn should_propagate_processor_serialize_error() {
struct ErroringProcessor;
impl ReflectSerializerProcessor for ErroringProcessor {
fn try_serialize<S>(
&self,
value: &dyn PartialReflect,
_: &TypeRegistry,
serializer: S,
) -> Result<Result<S::Ok, S>, S::Error>
where
S: Serializer,
{
let Some(value) = value.try_as_reflect() else {
return Ok(Err(serializer));
};
let type_id = value.reflect_type_info().type_id();
if type_id == TypeId::of::<i32>() {
Err(serde::ser::Error::custom("my custom serialize error"))
} else {
Ok(Err(serializer))
}
}
}
let value = 123_i32;
let registry = TypeRegistry::new();
let processor = ErroringProcessor;
let serializer = ReflectSerializer::with_processor(&value, &registry, &processor);
let error = ron::ser::to_string_pretty(&serializer, PrettyConfig::default()).unwrap_err();
#[cfg(feature = "debug_stack")]
assert_eq!(
error,
ron::Error::Message("my custom serialize error (stack: `i32`)".to_string())
);
#[cfg(not(feature = "debug_stack"))]
assert_eq!(
error,
ron::Error::Message("my custom serialize error".to_string())
);
}
#[cfg(feature = "functions")]
mod functions {
use super::*;
use crate::func::{DynamicFunction, IntoFunction};
use alloc::string::ToString;
#[test]
fn should_not_serialize_function() {
#[derive(Reflect)]
#[reflect(from_reflect = false)]
struct MyStruct {
func: DynamicFunction<'static>,
}
let value: Box<dyn Reflect> = Box::new(MyStruct {
func: String::new.into_function(),
});
let registry = TypeRegistry::new();
let serializer = ReflectSerializer::new(value.as_partial_reflect(), &registry);
let error = ron::ser::to_string(&serializer).unwrap_err();
#[cfg(feature = "debug_stack")]
assert_eq!(
error,
ron::Error::Message("functions cannot be serialized (stack: `bevy_reflect::serde::ser::tests::functions::MyStruct`)".to_string())
);
#[cfg(not(feature = "debug_stack"))]
assert_eq!(
error,
ron::Error::Message("functions cannot be serialized".to_string())
);
}
}
#[cfg(feature = "debug_stack")]
mod debug_stack {
use super::*;
#[test]
fn should_report_context_in_errors() {
#[derive(Reflect)]
struct Foo {
bar: Bar,
}
#[derive(Reflect)]
struct Bar {
some_other_field: Option<u32>,
baz: Baz,
}
#[derive(Reflect)]
struct Baz {
value: Vec<RangeInclusive<f32>>,
}
let value = Foo {
bar: Bar {
some_other_field: Some(123),
baz: Baz {
value: vec![0.0..=1.0],
},
},
};
let registry = TypeRegistry::new();
let serializer = ReflectSerializer::new(&value, &registry);
let error = ron::ser::to_string(&serializer).unwrap_err();
assert_eq!(
error,
ron::Error::Message(
"type `core::ops::RangeInclusive<f32>` is not registered in the type registry (stack: `bevy_reflect::serde::ser::tests::debug_stack::Foo` -> `bevy_reflect::serde::ser::tests::debug_stack::Bar` -> `bevy_reflect::serde::ser::tests::debug_stack::Baz` -> `alloc::vec::Vec<core::ops::RangeInclusive<f32>>` -> `core::ops::RangeInclusive<f32>`)".to_string()
)
);
}
}
}

View File

@@ -0,0 +1,196 @@
use serde::Serializer;
use crate::{PartialReflect, TypeRegistry};
/// Allows overriding the default serialization behavior of
/// [`ReflectSerializer`] and [`TypedReflectSerializer`] for specific values.
///
/// When serializing a reflected value, you may want to override the default
/// behavior and use your own logic for serialization. This logic may also be
/// context-dependent, and only apply for a single use of your
/// [`ReflectSerializer`]. To achieve this, you can create a processor and pass
/// it into your serializer.
///
/// Whenever the serializer attempts to serialize a value, it will first call
/// [`try_serialize`] on your processor, which may take ownership of the
/// serializer and write into the serializer (successfully or not), or return
/// ownership of the serializer back, and continue with the default logic.
///
/// The deserialization equivalent of this is [`ReflectDeserializerProcessor`].
///
/// # Compared to [`SerializeWithRegistry`]
///
/// [`SerializeWithRegistry`] allows you to define how your type will be
/// serialized by a [`TypedReflectSerializer`], given the extra context of the
/// [`TypeRegistry`]. If your type can be serialized entirely using that, then
/// you should prefer implementing that trait instead of using a processor.
///
/// However, you may need more context-dependent data which is only present in
/// the scope where you create the [`TypedReflectSerializer`]. For example, if
/// you need to use a reference to a value while serializing, then there is no
/// way to do this with [`SerializeWithRegistry`] as you can't pass that
/// reference into anywhere. This is where a processor is useful, as the
/// processor can capture local variables.
///
/// A [`ReflectSerializerProcessor`] always takes priority over a
/// [`SerializeWithRegistry`] implementation, so this is also useful for
/// overriding serialization behavior if you need to do something custom.
///
/// # Examples
///
/// Serializing a reflected value when saving an asset to disk, and replacing
/// asset handles with the handle path (if it has one):
///
/// ```
/// # use core::any::Any;
/// # use serde::Serialize;
/// # use bevy_reflect::{PartialReflect, Reflect, TypeData, TypeRegistry};
/// # use bevy_reflect::serde::{ReflectSerializer, ReflectSerializerProcessor};
/// #
/// # #[derive(Debug, Clone, Reflect)]
/// # struct Handle<T>(T);
/// # #[derive(Debug, Clone, Reflect)]
/// # struct Mesh;
/// #
/// # struct ReflectHandle;
/// # impl TypeData for ReflectHandle {
/// # fn clone_type_data(&self) -> Box<dyn TypeData> {
/// # unimplemented!()
/// # }
/// # }
/// # impl ReflectHandle {
/// # fn downcast_handle_untyped(&self, handle: &(dyn Any + 'static)) -> Option<UntypedHandle> {
/// # unimplemented!()
/// # }
/// # }
/// #
/// # #[derive(Debug, Clone)]
/// # struct UntypedHandle;
/// # impl UntypedHandle {
/// # fn path(&self) -> Option<&str> {
/// # unimplemented!()
/// # }
/// # }
/// # type AssetError = Box<dyn core::error::Error>;
/// #
/// #[derive(Debug, Clone, Reflect)]
/// struct MyAsset {
/// name: String,
/// mesh: Handle<Mesh>,
/// }
///
/// struct HandleProcessor;
///
/// impl ReflectSerializerProcessor for HandleProcessor {
/// fn try_serialize<S>(
/// &self,
/// value: &dyn PartialReflect,
/// registry: &TypeRegistry,
/// serializer: S,
/// ) -> Result<Result<S::Ok, S>, S::Error>
/// where
/// S: serde::Serializer,
/// {
/// let Some(value) = value.try_as_reflect() else {
/// // we don't have any info on this type; do the default serialization logic
/// return Ok(Err(serializer));
/// };
/// let type_id = value.reflect_type_info().type_id();
/// let Some(reflect_handle) = registry.get_type_data::<ReflectHandle>(type_id) else {
/// // this isn't a `Handle<T>`
/// return Ok(Err(serializer));
/// };
///
/// let untyped_handle = reflect_handle
/// .downcast_handle_untyped(value.as_any())
/// .unwrap();
/// if let Some(path) = untyped_handle.path() {
/// Ok(Ok(serializer.serialize_str(path)?))
/// } else {
/// Ok(Ok(serializer.serialize_unit()?))
/// }
/// }
/// }
///
/// fn save(type_registry: &TypeRegistry, asset: &MyAsset) -> Result<Vec<u8>, AssetError> {
/// let mut asset_bytes = Vec::new();
///
/// let processor = HandleProcessor;
/// let serializer = ReflectSerializer::with_processor(asset, type_registry, &processor);
/// let mut ron_serializer = ron::Serializer::new(&mut asset_bytes, None)?;
///
/// serializer.serialize(&mut ron_serializer)?;
/// Ok(asset_bytes)
/// }
/// ```
///
/// [`ReflectSerializer`]: crate::serde::ReflectSerializer
/// [`TypedReflectSerializer`]: crate::serde::TypedReflectSerializer
/// [`try_serialize`]: Self::try_serialize
/// [`SerializeWithRegistry`]: crate::serde::SerializeWithRegistry
/// [`ReflectDeserializerProcessor`]: crate::serde::ReflectDeserializerProcessor
pub trait ReflectSerializerProcessor {
/// Attempts to serialize the value which a [`TypedReflectSerializer`] is
/// currently looking at.
///
/// If you want to override the default serialization, return
/// `Ok(Ok(value))` with an `Ok` output from the serializer.
///
/// If you don't want to override the serialization, return ownership of
/// the serializer back via `Ok(Err(serializer))`.
///
/// You can use the type registry to read info about the type you're
/// serializing, or just try to downcast the value directly:
///
/// ```
/// # use bevy_reflect::{TypeRegistration, TypeRegistry, PartialReflect};
/// # use bevy_reflect::serde::ReflectSerializerProcessor;
/// # use core::any::TypeId;
/// struct I32AsStringProcessor;
///
/// impl ReflectSerializerProcessor for I32AsStringProcessor {
/// fn try_serialize<S>(
/// &self,
/// value: &dyn PartialReflect,
/// registry: &TypeRegistry,
/// serializer: S,
/// ) -> Result<Result<S::Ok, S>, S::Error>
/// where
/// S: serde::Serializer
/// {
/// if let Some(value) = value.try_downcast_ref::<i32>() {
/// let value_as_string = format!("{value:?}");
/// Ok(Ok(serializer.serialize_str(&value_as_string)?))
/// } else {
/// // Not an `i32`, just do the default serialization
/// Ok(Err(serializer))
/// }
/// }
/// }
/// ```
///
/// [`TypedReflectSerializer`]: crate::serde::TypedReflectSerializer
/// [`Reflect`]: crate::Reflect
fn try_serialize<S>(
&self,
value: &dyn PartialReflect,
registry: &TypeRegistry,
serializer: S,
) -> Result<Result<S::Ok, S>, S::Error>
where
S: Serializer;
}
impl ReflectSerializerProcessor for () {
fn try_serialize<S>(
&self,
_value: &dyn PartialReflect,
_registry: &TypeRegistry,
serializer: S,
) -> Result<Result<S::Ok, S>, S::Error>
where
S: Serializer,
{
Ok(Err(serializer))
}
}

View File

@@ -0,0 +1,19 @@
use alloc::boxed::Box;
use core::ops::Deref;
/// A type-erased serializable value.
pub enum Serializable<'a> {
Owned(Box<dyn erased_serde::Serialize + 'a>),
Borrowed(&'a dyn erased_serde::Serialize),
}
impl<'a> Deref for Serializable<'a> {
type Target = dyn erased_serde::Serialize + 'a;
fn deref(&self) -> &Self::Target {
match self {
Serializable::Borrowed(serialize) => serialize,
Serializable::Owned(serialize) => serialize,
}
}
}

View File

@@ -0,0 +1,101 @@
use crate::{FromType, Reflect, TypeRegistry};
use alloc::boxed::Box;
use serde::{Serialize, Serializer};
/// Trait used to provide finer control when serializing a reflected type with one of
/// the reflection serializers.
///
/// This trait is the reflection equivalent of `serde`'s [`Serialize`] trait.
/// The main difference is that this trait provides access to the [`TypeRegistry`],
/// which means that we can use the registry and all its stored type information
/// to serialize our type.
///
/// This can be useful when writing a custom reflection serializer where we may
/// want to handle parts of the serialization process, but temporarily pass control
/// to the standard reflection serializer for other parts.
///
/// For the deserialization equivalent of this trait, see [`DeserializeWithRegistry`].
///
/// # Rationale
///
/// Without this trait and its associated [type data], such a serializer would have to
/// write out all of the serialization logic itself, possibly including
/// unnecessary code duplication and trivial implementations.
///
/// This is because a normal [`Serialize`] implementation has no knowledge of the
/// [`TypeRegistry`] and therefore cannot create a reflection-based serializer for
/// nested items.
///
/// # Implementors
///
/// In order for this to work with the reflection serializers like [`TypedReflectSerializer`]
/// and [`ReflectSerializer`], implementors should be sure to register the
/// [`ReflectSerializeWithRegistry`] type data.
/// This can be done [via the registry] or by adding `#[reflect(SerializeWithRegistry)]` to
/// the type definition.
///
/// [`DeserializeWithRegistry`]: crate::serde::DeserializeWithRegistry
/// [type data]: ReflectSerializeWithRegistry
/// [`TypedReflectSerializer`]: crate::serde::TypedReflectSerializer
/// [`ReflectSerializer`]: crate::serde::ReflectSerializer
/// [via the registry]: TypeRegistry::register_type_data
pub trait SerializeWithRegistry {
fn serialize<S>(&self, serializer: S, registry: &TypeRegistry) -> Result<S::Ok, S::Error>
where
S: Serializer;
}
/// Type data used to serialize a [`Reflect`] type with a custom [`SerializeWithRegistry`] implementation.
#[derive(Clone)]
pub struct ReflectSerializeWithRegistry {
serialize: for<'a> fn(
value: &'a dyn Reflect,
registry: &'a TypeRegistry,
) -> Box<dyn erased_serde::Serialize + 'a>,
}
impl ReflectSerializeWithRegistry {
/// Serialize a [`Reflect`] type with this type data's custom [`SerializeWithRegistry`] implementation.
pub fn serialize<S>(
&self,
value: &dyn Reflect,
serializer: S,
registry: &TypeRegistry,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
((self.serialize)(value, registry)).serialize(serializer)
}
}
impl<T: Reflect + SerializeWithRegistry> FromType<T> for ReflectSerializeWithRegistry {
fn from_type() -> Self {
Self {
serialize: |value: &dyn Reflect, registry| {
let value = value.downcast_ref::<T>().unwrap_or_else(|| {
panic!(
"Expected value to be of type {} but received {}",
core::any::type_name::<T>(),
value.reflect_type_path()
)
});
Box::new(SerializableWithRegistry { value, registry })
},
}
}
}
struct SerializableWithRegistry<'a, T: SerializeWithRegistry> {
value: &'a T,
registry: &'a TypeRegistry,
}
impl<'a, T: SerializeWithRegistry> Serialize for SerializableWithRegistry<'a, T> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.value.serialize(serializer, self.registry)
}
}

View File

@@ -0,0 +1,326 @@
#[cfg(feature = "debug_stack")]
use crate::serde::ser::error_utils::TYPE_INFO_STACK;
use crate::{
serde::ser::{
arrays::ArraySerializer, custom_serialization::try_custom_serialize, enums::EnumSerializer,
error_utils::make_custom_error, lists::ListSerializer, maps::MapSerializer,
sets::SetSerializer, structs::StructSerializer, tuple_structs::TupleStructSerializer,
tuples::TupleSerializer,
},
PartialReflect, ReflectRef, TypeRegistry,
};
use serde::{ser::SerializeMap, Serialize, Serializer};
use super::ReflectSerializerProcessor;
/// A general purpose serializer for reflected types.
///
/// 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.
///
/// If you want to override serialization for specific values, you can pass in
/// a reference to a [`ReflectSerializerProcessor`] which will take priority
/// over all other serialization methods - see [`with_processor`].
///
/// # 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, &registry);
/// 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
/// [`with_processor`]: Self::with_processor
pub struct ReflectSerializer<'a, P = ()> {
value: &'a dyn PartialReflect,
registry: &'a TypeRegistry,
processor: Option<&'a P>,
}
impl<'a> ReflectSerializer<'a, ()> {
/// Creates a serializer with no processor.
///
/// If you want to add custom logic for serializing certain values, use
/// [`with_processor`].
///
/// [`with_processor`]: Self::with_processor
pub fn new(value: &'a dyn PartialReflect, registry: &'a TypeRegistry) -> Self {
Self {
value,
registry,
processor: None,
}
}
}
impl<'a, P: ReflectSerializerProcessor> ReflectSerializer<'a, P> {
/// Creates a serializer with a processor.
///
/// If you do not need any custom logic for handling certain values, use
/// [`new`].
///
/// [`new`]: Self::new
pub fn with_processor(
value: &'a dyn PartialReflect,
registry: &'a TypeRegistry,
processor: &'a P,
) -> Self {
Self {
value,
registry,
processor: Some(processor),
}
}
}
impl<P: ReflectSerializerProcessor> Serialize for ReflectSerializer<'_, P> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut state = serializer.serialize_map(Some(1))?;
state.serialize_entry(
self.value
.get_represented_type_info()
.ok_or_else(|| {
if self.value.is_dynamic() {
make_custom_error(format_args!(
"cannot serialize dynamic value without represented type: `{}`",
self.value.reflect_type_path()
))
} else {
make_custom_error(format_args!(
"cannot get type info for `{}`",
self.value.reflect_type_path()
))
}
})?
.type_path(),
&TypedReflectSerializer::new_internal(self.value, self.registry, self.processor),
)?;
state.end()
}
}
/// 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.
///
/// If you want to override serialization for specific values, you can pass in
/// a reference to a [`ReflectSerializerProcessor`] which will take priority
/// over all other serialization methods - see [`with_processor`].
///
/// # 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, &registry);
/// let output = ron::to_string(&reflect_serializer).unwrap();
///
/// assert_eq!(output, r#"(value:123)"#);
/// ```
///
/// [`TypedReflectDeserializer`]: crate::serde::TypedReflectDeserializer
/// [type path]: crate::TypePath::type_path
/// [`with_processor`]: Self::with_processor
pub struct TypedReflectSerializer<'a, P = ()> {
value: &'a dyn PartialReflect,
registry: &'a TypeRegistry,
processor: Option<&'a P>,
}
impl<'a> TypedReflectSerializer<'a, ()> {
/// Creates a serializer with no processor.
///
/// If you want to add custom logic for serializing certain values, use
/// [`with_processor`].
///
/// [`with_processor`]: Self::with_processor
pub fn new(value: &'a dyn PartialReflect, registry: &'a TypeRegistry) -> Self {
#[cfg(feature = "debug_stack")]
TYPE_INFO_STACK.set(crate::type_info_stack::TypeInfoStack::new());
Self {
value,
registry,
processor: None,
}
}
}
impl<'a, P> TypedReflectSerializer<'a, P> {
/// Creates a serializer with a processor.
///
/// If you do not need any custom logic for handling certain values, use
/// [`new`].
///
/// [`new`]: Self::new
pub fn with_processor(
value: &'a dyn PartialReflect,
registry: &'a TypeRegistry,
processor: &'a P,
) -> Self {
#[cfg(feature = "debug_stack")]
TYPE_INFO_STACK.set(crate::type_info_stack::TypeInfoStack::new());
Self {
value,
registry,
processor: Some(processor),
}
}
/// An internal constructor for creating a serializer without resetting the type info stack.
pub(super) fn new_internal(
value: &'a dyn PartialReflect,
registry: &'a TypeRegistry,
processor: Option<&'a P>,
) -> Self {
Self {
value,
registry,
processor,
}
}
}
impl<P: ReflectSerializerProcessor> Serialize for TypedReflectSerializer<'_, P> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
#[cfg(feature = "debug_stack")]
{
if let Some(info) = self.value.get_represented_type_info() {
TYPE_INFO_STACK.with_borrow_mut(|stack| stack.push(info));
}
}
// First, check if our processor wants to serialize this type
// This takes priority over any other serialization operations
let serializer = if let Some(processor) = self.processor {
match processor.try_serialize(self.value, self.registry, serializer) {
Ok(Ok(value)) => {
return Ok(value);
}
Err(err) => {
return Err(make_custom_error(err));
}
Ok(Err(serializer)) => serializer,
}
} else {
serializer
};
// Handle both Value case and types that have a custom `Serialize`
let (serializer, error) = match try_custom_serialize(self.value, self.registry, serializer)
{
Ok(result) => return result,
Err(value) => value,
};
let output = match self.value.reflect_ref() {
ReflectRef::Struct(struct_value) => StructSerializer {
struct_value,
registry: self.registry,
processor: self.processor,
}
.serialize(serializer),
ReflectRef::TupleStruct(tuple_struct) => TupleStructSerializer {
tuple_struct,
registry: self.registry,
processor: self.processor,
}
.serialize(serializer),
ReflectRef::Tuple(tuple) => TupleSerializer {
tuple,
registry: self.registry,
processor: self.processor,
}
.serialize(serializer),
ReflectRef::List(list) => ListSerializer {
list,
registry: self.registry,
processor: self.processor,
}
.serialize(serializer),
ReflectRef::Array(array) => ArraySerializer {
array,
registry: self.registry,
processor: self.processor,
}
.serialize(serializer),
ReflectRef::Map(map) => MapSerializer {
map,
registry: self.registry,
processor: self.processor,
}
.serialize(serializer),
ReflectRef::Set(set) => SetSerializer {
set,
registry: self.registry,
processor: self.processor,
}
.serialize(serializer),
ReflectRef::Enum(enum_value) => EnumSerializer {
enum_value,
registry: self.registry,
processor: self.processor,
}
.serialize(serializer),
#[cfg(feature = "functions")]
ReflectRef::Function(_) => Err(make_custom_error("functions cannot be serialized")),
ReflectRef::Opaque(_) => Err(error),
};
#[cfg(feature = "debug_stack")]
TYPE_INFO_STACK.with_borrow_mut(crate::type_info_stack::TypeInfoStack::pop);
output
}
}

View File

@@ -0,0 +1,28 @@
use crate::{serde::TypedReflectSerializer, Set, TypeRegistry};
use serde::{ser::SerializeSeq, Serialize};
use super::ReflectSerializerProcessor;
/// A serializer for [`Set`] values.
pub(super) struct SetSerializer<'a, P> {
pub set: &'a dyn Set,
pub registry: &'a TypeRegistry,
pub processor: Option<&'a P>,
}
impl<P: ReflectSerializerProcessor> Serialize for SetSerializer<'_, P> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut state = serializer.serialize_seq(Some(self.set.len()))?;
for value in self.set.iter() {
state.serialize_element(&TypedReflectSerializer::new_internal(
value,
self.registry,
self.processor,
))?;
}
state.end()
}
}

View File

@@ -0,0 +1,62 @@
use crate::{
serde::{ser::error_utils::make_custom_error, SerializationData, TypedReflectSerializer},
Struct, TypeInfo, TypeRegistry,
};
use serde::{ser::SerializeStruct, Serialize};
use super::ReflectSerializerProcessor;
/// A serializer for [`Struct`] values.
pub(super) struct StructSerializer<'a, P> {
pub struct_value: &'a dyn Struct,
pub registry: &'a TypeRegistry,
pub processor: Option<&'a P>,
}
impl<P: ReflectSerializerProcessor> Serialize for StructSerializer<'_, P> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let type_info = self
.struct_value
.get_represented_type_info()
.ok_or_else(|| {
make_custom_error(format_args!(
"cannot get type info for `{}`",
self.struct_value.reflect_type_path()
))
})?;
let struct_info = match type_info {
TypeInfo::Struct(struct_info) => struct_info,
info => {
return Err(make_custom_error(format_args!(
"expected struct type but received {info:?}"
)));
}
};
let serialization_data = self
.registry
.get(type_info.type_id())
.and_then(|registration| registration.data::<SerializationData>());
let ignored_len = serialization_data.map(SerializationData::len).unwrap_or(0);
let mut state = serializer.serialize_struct(
struct_info.type_path_table().ident().unwrap(),
self.struct_value.field_len() - ignored_len,
)?;
for (index, value) in self.struct_value.iter_fields().enumerate() {
if serialization_data.is_some_and(|data| data.is_field_skipped(index)) {
continue;
}
let key = struct_info.field_at(index).unwrap().name();
state.serialize_field(
key,
&TypedReflectSerializer::new_internal(value, self.registry, self.processor),
)?;
}
state.end()
}
}

View File

@@ -0,0 +1,71 @@
use crate::{
serde::{ser::error_utils::make_custom_error, SerializationData, TypedReflectSerializer},
TupleStruct, TypeInfo, TypeRegistry,
};
use serde::{ser::SerializeTupleStruct, Serialize};
use super::ReflectSerializerProcessor;
/// A serializer for [`TupleStruct`] values.
pub(super) struct TupleStructSerializer<'a, P> {
pub tuple_struct: &'a dyn TupleStruct,
pub registry: &'a TypeRegistry,
pub processor: Option<&'a P>,
}
impl<P: ReflectSerializerProcessor> Serialize for TupleStructSerializer<'_, P> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let type_info = self
.tuple_struct
.get_represented_type_info()
.ok_or_else(|| {
make_custom_error(format_args!(
"cannot get type info for `{}`",
self.tuple_struct.reflect_type_path()
))
})?;
let tuple_struct_info = match type_info {
TypeInfo::TupleStruct(tuple_struct_info) => tuple_struct_info,
info => {
return Err(make_custom_error(format_args!(
"expected tuple struct type but received {info:?}"
)));
}
};
let serialization_data = self
.registry
.get(type_info.type_id())
.and_then(|registration| registration.data::<SerializationData>());
let ignored_len = serialization_data.map(SerializationData::len).unwrap_or(0);
if self.tuple_struct.field_len() == 1 && serialization_data.is_none() {
let field = self.tuple_struct.field(0).unwrap();
return serializer.serialize_newtype_struct(
tuple_struct_info.type_path_table().ident().unwrap(),
&TypedReflectSerializer::new_internal(field, self.registry, self.processor),
);
}
let mut state = serializer.serialize_tuple_struct(
tuple_struct_info.type_path_table().ident().unwrap(),
self.tuple_struct.field_len() - ignored_len,
)?;
for (index, value) in self.tuple_struct.iter_fields().enumerate() {
if serialization_data.is_some_and(|data| data.is_field_skipped(index)) {
continue;
}
state.serialize_field(&TypedReflectSerializer::new_internal(
value,
self.registry,
self.processor,
))?;
}
state.end()
}
}

View File

@@ -0,0 +1,29 @@
use crate::{serde::TypedReflectSerializer, Tuple, TypeRegistry};
use serde::{ser::SerializeTuple, Serialize};
use super::ReflectSerializerProcessor;
/// A serializer for [`Tuple`] values.
pub(super) struct TupleSerializer<'a, P> {
pub tuple: &'a dyn Tuple,
pub registry: &'a TypeRegistry,
pub processor: Option<&'a P>,
}
impl<P: ReflectSerializerProcessor> Serialize for TupleSerializer<'_, P> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut state = serializer.serialize_tuple(self.tuple.field_len())?;
for value in self.tuple.iter_fields() {
state.serialize_element(&TypedReflectSerializer::new_internal(
value,
self.registry,
self.processor,
))?;
}
state.end()
}
}

View File

@@ -0,0 +1,136 @@
use crate::Reflect;
use alloc::boxed::Box;
use bevy_platform::collections::{hash_map::Iter, HashMap};
/// Contains data relevant to the automatic reflect powered (de)serialization of a type.
#[derive(Debug, Clone)]
pub struct SerializationData {
skipped_fields: HashMap<usize, SkippedField>,
}
impl SerializationData {
/// Creates a new `SerializationData` instance with the given skipped fields.
///
/// # Arguments
///
/// * `skipped_iter`: The iterator of field indices to be skipped during (de)serialization.
/// Indices are assigned only to reflected fields.
/// Ignored fields (i.e. those marked `#[reflect(ignore)]`) are implicitly skipped
/// and do not need to be included in this iterator.
pub fn new<I: Iterator<Item = (usize, SkippedField)>>(skipped_iter: I) -> Self {
Self {
skipped_fields: skipped_iter.collect(),
}
}
/// Returns true if the given index corresponds to a field meant to be skipped during (de)serialization.
///
/// # Example
///
/// ```
/// # use core::any::TypeId;
/// # use bevy_reflect::{Reflect, Struct, TypeRegistry, serde::SerializationData};
/// #[derive(Reflect)]
/// struct MyStruct {
/// serialize_me: i32,
/// #[reflect(skip_serializing)]
/// skip_me: i32
/// }
///
/// let mut registry = TypeRegistry::new();
/// registry.register::<MyStruct>();
///
/// let my_struct = MyStruct {
/// serialize_me: 123,
/// skip_me: 321,
/// };
///
/// let serialization_data = registry.get_type_data::<SerializationData>(TypeId::of::<MyStruct>()).unwrap();
///
/// for (idx, field) in my_struct.iter_fields().enumerate(){
/// if serialization_data.is_field_skipped(idx) {
/// // Skipped!
/// assert_eq!(1, idx);
/// } else {
/// // Not Skipped!
/// assert_eq!(0, idx);
/// }
/// }
/// ```
pub fn is_field_skipped(&self, index: usize) -> bool {
self.skipped_fields.contains_key(&index)
}
/// Generates a default instance of the skipped field at the given index.
///
/// Returns `None` if the field is not skipped.
///
/// # Example
///
/// ```
/// # use core::any::TypeId;
/// # use bevy_reflect::{Reflect, Struct, TypeRegistry, serde::SerializationData};
/// #[derive(Reflect)]
/// struct MyStruct {
/// serialize_me: i32,
/// #[reflect(skip_serializing)]
/// #[reflect(default = "skip_me_default")]
/// skip_me: i32
/// }
///
/// fn skip_me_default() -> i32 {
/// 789
/// }
///
/// let mut registry = TypeRegistry::new();
/// registry.register::<MyStruct>();
///
/// let serialization_data = registry.get_type_data::<SerializationData>(TypeId::of::<MyStruct>()).unwrap();
/// assert_eq!(789, serialization_data.generate_default(1).unwrap().take::<i32>().unwrap());
/// ```
pub fn generate_default(&self, index: usize) -> Option<Box<dyn Reflect>> {
self.skipped_fields
.get(&index)
.map(SkippedField::generate_default)
}
/// Returns the number of skipped fields.
pub fn len(&self) -> usize {
self.skipped_fields.len()
}
/// Returns true if there are no skipped fields.
pub fn is_empty(&self) -> bool {
self.skipped_fields.is_empty()
}
/// Returns an iterator over the skipped fields.
///
/// Each item in the iterator is a tuple containing:
/// 1. The reflected index of the field
/// 2. The (de)serialization metadata of the field
pub fn iter_skipped(&self) -> Iter<'_, usize, SkippedField> {
self.skipped_fields.iter()
}
}
/// Data needed for (de)serialization of a skipped field.
#[derive(Debug, Clone)]
pub struct SkippedField {
default_fn: fn() -> Box<dyn Reflect>,
}
impl SkippedField {
/// Create a new `SkippedField`.
///
/// # Arguments
///
/// * `default_fn`: A function pointer used to generate a default instance of the field.
pub fn new(default_fn: fn() -> Box<dyn Reflect>) -> Self {
Self { default_fn }
}
/// Generates a default instance of the field.
pub fn generate_default(&self) -> Box<dyn Reflect> {
(self.default_fn)()
}
}