bevy_reflect: Refactor serde module (#15107)

# Objective

The `ser` and `de` modules in `bevy_reflect/serde` are very long and
difficult to navigate.

## Solution

Refactor both modules into many smaller modules that each have a single
primary focus (i.e. a `structs` module that only handles struct
serialization/deserialization).

I chose to keep the `ser` and `de` modules separate. We could have
instead broken it up kind (e.g. lists, maps, etc.), but I think this is
a little cleaner. Serialization and deserialization, while related, can
be very different. So keeping them separated makes sense for
organizational purposes.

That being said, if people disagree and think we should structure this a
different way, I am open to changing it.

Note that this PR's changes are mainly structural. There are a few
places I refactored code to reduce duplication and to make things a bit
cleaner, but these are largely cosmetic and shouldn't have any impact on
behavior.

### Other Details

This PR also hides a lot of the internal logic from being exported.
These were originally public, but it's unlikely they really saw any use
outside of these modules. In fact, you don't really gain anything by
using them outside of this module either.

By privatizing these fields and items, we also set ourselves up for more
easily changing internal logic around without involving a breaking
change.

I also chose not to mess around with tests since that would really blow
up the diff haha.

## Testing

You can test locally by running:

```
cargo test --package bevy_reflect --all-features
```

---

## Migration Guide

The fields on `ReflectSerializer` and `TypedReflectSerializer` are now
private. To instantiate, the corresponding constructor must be used:

```rust
// BEFORE
let serializer = ReflectSerializer {
    value: &my_value,
    registry: &type_registry,
};

// AFTER
let serializer = ReflectSerializer::new(&my_value, &type_registry);
```

Additionally, the following types are no longer public:

- `ArraySerializer`
- `EnumSerializer`
- `ListSerializer`
- `MapSerializer`
- `ReflectValueSerializer` (fully removed)
- `StructSerializer`
- `TupleSerializer`
- `TupleStructSerializer`

As well as the following traits:

- `DeserializeValue` (fully removed)
This commit is contained in:
Gino Valente 2024-09-09 07:03:42 -07:00 committed by GitHub
parent a0faf9cd01
commit ba3d9b3fb6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
29 changed files with 2954 additions and 2724 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,53 @@
use crate::serde::de::registration_utils::try_get_registration;
use crate::serde::TypedReflectDeserializer;
use crate::{ArrayInfo, DynamicArray, TypeRegistry};
use core::fmt::Formatter;
use serde::de::{Error, SeqAccess, Visitor};
use std::fmt;
/// A [`Visitor`] for deserializing [`Array`] values.
///
/// [`Array`]: crate::Array
pub(super) struct ArrayVisitor<'a> {
array_info: &'static ArrayInfo,
registry: &'a TypeRegistry,
}
impl<'a> ArrayVisitor<'a> {
pub fn new(array_info: &'static ArrayInfo, registry: &'a TypeRegistry) -> Self {
Self {
array_info,
registry,
}
}
}
impl<'a, 'de> Visitor<'de> for ArrayVisitor<'a> {
type Value = DynamicArray;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("reflected array value")
}
fn visit_seq<V>(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(registration, self.registry))?
{
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,333 @@
use crate::serde::de::arrays::ArrayVisitor;
use crate::serde::de::enums::EnumVisitor;
use crate::serde::de::lists::ListVisitor;
use crate::serde::de::maps::MapVisitor;
use crate::serde::de::options::OptionVisitor;
use crate::serde::de::sets::SetVisitor;
use crate::serde::de::structs::StructVisitor;
use crate::serde::de::tuple_structs::TupleStructVisitor;
use crate::serde::de::tuples::TupleVisitor;
use crate::serde::TypeRegistrationDeserializer;
use crate::{PartialReflect, ReflectDeserialize, TypeInfo, TypeRegistration, TypeRegistry};
use core::fmt::Formatter;
use serde::de::{DeserializeSeed, Error, IgnoredAny, MapAccess, Visitor};
use std::fmt;
/// A general purpose deserializer for reflected types.
///
/// This is the deserializer counterpart to [`ReflectSerializer`].
///
/// See [`TypedReflectDeserializer`] for a deserializer that expects a known type.
///
/// # Input
///
/// This deserializer expects a map with a single entry,
/// where the key is the _full_ [type path] of the reflected type
/// and the value is the serialized data.
///
/// # Output
///
/// This deserializer will return a [`Box<dyn Reflect>`] containing the deserialized data.
///
/// For value types (i.e. [`ReflectKind::Value`]) or types that register [`ReflectDeserialize`] type data,
/// this `Box` will contain the expected type.
/// For example, deserializing an `i32` will return a `Box<i32>` (as a `Box<dyn Reflect>`).
///
/// Otherwise, this `Box` will contain the dynamic equivalent.
/// For example, a deserialized struct might return a [`Box<DynamicStruct>`]
/// and a deserialized `Vec` might return a [`Box<DynamicList>`].
///
/// This means that if the actual type is needed, these dynamic representations will need to
/// be converted to the concrete type using [`FromReflect`] or [`ReflectFromReflect`].
///
/// # Example
///
/// ```
/// # use serde::de::DeserializeSeed;
/// # use bevy_reflect::prelude::*;
/// # use bevy_reflect::{DynamicStruct, TypeRegistry, serde::ReflectDeserializer};
/// #[derive(Reflect, PartialEq, Debug)]
/// #[type_path = "my_crate"]
/// struct MyStruct {
/// value: i32
/// }
///
/// let mut registry = TypeRegistry::default();
/// registry.register::<MyStruct>();
///
/// let input = r#"{
/// "my_crate::MyStruct": (
/// value: 123
/// )
/// }"#;
///
/// let mut deserializer = ron::Deserializer::from_str(input).unwrap();
/// let reflect_deserializer = ReflectDeserializer::new(&registry);
///
/// let output: Box<dyn PartialReflect> = reflect_deserializer.deserialize(&mut deserializer).unwrap();
///
/// // Since `MyStruct` is not a value 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::Value`]: crate::ReflectKind::Value
/// [`ReflectDeserialize`]: crate::ReflectDeserialize
/// [`Box<DynamicStruct>`]: crate::DynamicStruct
/// [`Box<DynamicList>`]: crate::DynamicList
/// [`FromReflect`]: crate::FromReflect
/// [`ReflectFromReflect`]: crate::ReflectFromReflect
pub struct ReflectDeserializer<'a> {
registry: &'a TypeRegistry,
}
impl<'a> ReflectDeserializer<'a> {
pub fn new(registry: &'a TypeRegistry) -> Self {
Self { registry }
}
}
impl<'a, 'de> DeserializeSeed<'de> for ReflectDeserializer<'a> {
type Value = Box<dyn PartialReflect>;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>,
{
struct UntypedReflectDeserializerVisitor<'a> {
registry: &'a TypeRegistry,
}
impl<'a, 'de> Visitor<'de> for UntypedReflectDeserializerVisitor<'a> {
type Value = Box<dyn 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 {
registration,
registry: self.registry,
})?;
if map.next_key::<IgnoredAny>()?.is_some() {
return Err(Error::invalid_length(2, &"a single entry"));
}
Ok(value)
}
}
deserializer.deserialize_map(UntypedReflectDeserializerVisitor {
registry: self.registry,
})
}
}
/// A deserializer for reflected types whose [`TypeRegistration`] is known.
///
/// This 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 value types (i.e. [`ReflectKind::Value`]) or types that register [`ReflectDeserialize`] type data,
/// this `Box` will contain the expected type.
/// For example, deserializing an `i32` will return a `Box<i32>` (as a `Box<dyn Reflect>`).
///
/// Otherwise, this `Box` will contain the dynamic equivalent.
/// For example, a deserialized struct might return a [`Box<DynamicStruct>`]
/// and a deserialized `Vec` might return a [`Box<DynamicList>`].
///
/// This means that if the actual type is needed, these dynamic representations will need to
/// be converted to the concrete type using [`FromReflect`] or [`ReflectFromReflect`].
///
/// # Example
///
/// ```
/// # use std::any::TypeId;
/// # use serde::de::DeserializeSeed;
/// # use bevy_reflect::prelude::*;
/// # use bevy_reflect::{DynamicStruct, TypeRegistry, serde::TypedReflectDeserializer};
/// #[derive(Reflect, PartialEq, Debug)]
/// struct MyStruct {
/// value: i32
/// }
///
/// let mut registry = TypeRegistry::default();
/// registry.register::<MyStruct>();
///
/// let input = r#"(
/// value: 123
/// )"#;
///
/// let registration = registry.get(TypeId::of::<MyStruct>()).unwrap();
///
/// let mut deserializer = ron::Deserializer::from_str(input).unwrap();
/// let reflect_deserializer = TypedReflectDeserializer::new(registration, &registry);
///
/// let output: Box<dyn PartialReflect> = reflect_deserializer.deserialize(&mut deserializer).unwrap();
///
/// // Since `MyStruct` is not a value 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::Value`]: crate::ReflectKind::Value
/// [`ReflectDeserialize`]: crate::ReflectDeserialize
/// [`Box<DynamicStruct>`]: crate::DynamicStruct
/// [`Box<DynamicList>`]: crate::DynamicList
/// [`FromReflect`]: crate::FromReflect
/// [`ReflectFromReflect`]: crate::ReflectFromReflect
pub struct TypedReflectDeserializer<'a> {
registration: &'a TypeRegistration,
registry: &'a TypeRegistry,
}
impl<'a> TypedReflectDeserializer<'a> {
pub fn new(registration: &'a TypeRegistration, registry: &'a TypeRegistry) -> Self {
Self {
registration,
registry,
}
}
}
impl<'a, 'de> DeserializeSeed<'de> for TypedReflectDeserializer<'a> {
type Value = Box<dyn PartialReflect>;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>,
{
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());
}
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::new(struct_info, self.registration, self.registry),
)?;
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 = deserializer.deserialize_tuple_struct(
tuple_struct_info.type_path_table().ident().unwrap(),
tuple_struct_info.field_len(),
TupleStructVisitor::new(tuple_struct_info, self.registration, self.registry),
)?;
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::new(list_info, self.registry))?;
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::new(array_info, self.registry),
)?;
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::new(map_info, self.registry))?;
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::new(set_info, self.registry))?;
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::new(tuple_info, self.registration, self.registry),
)?;
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::new(enum_info, self.registry))?
} else {
deserializer.deserialize_enum(
enum_info.type_path_table().ident().unwrap(),
enum_info.variant_names(),
EnumVisitor::new(enum_info, self.registration, self.registry),
)?
};
dynamic_enum.set_represented_type(Some(self.registration.type_info()));
Ok(Box::new(dynamic_enum))
}
TypeInfo::Value(_) => {
// This case should already be handled
Err(Error::custom(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`",
)))
}
}
}
}

View file

@ -0,0 +1,198 @@
use crate::serde::de::helpers::ExpectedValues;
use crate::serde::de::registration_utils::try_get_registration;
use crate::serde::de::struct_utils::{visit_struct, visit_struct_seq};
use crate::serde::de::tuple_utils::{visit_tuple, TupleLikeInfo};
use crate::serde::TypedReflectDeserializer;
use crate::{
DynamicEnum, DynamicStruct, DynamicTuple, DynamicVariant, EnumInfo, StructVariantInfo,
TupleVariantInfo, TypeRegistration, TypeRegistry, VariantInfo,
};
use core::fmt::Formatter;
use serde::de::{DeserializeSeed, EnumAccess, Error, MapAccess, SeqAccess, VariantAccess, Visitor};
use std::fmt;
/// A [`Visitor`] for deserializing [`Enum`] values.
///
/// [`Enum`]: crate::Enum
pub(super) struct EnumVisitor<'a> {
enum_info: &'static EnumInfo,
registration: &'a TypeRegistration,
registry: &'a TypeRegistry,
}
impl<'a> EnumVisitor<'a> {
pub fn new(
enum_info: &'static EnumInfo,
registration: &'a TypeRegistration,
registry: &'a TypeRegistry,
) -> Self {
Self {
enum_info,
registration,
registry,
}
}
}
impl<'a, 'de> Visitor<'de> for EnumVisitor<'a> {
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,
},
)?
.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(
registration,
self.registry,
))?;
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,
},
)?
.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(|| {
Error::custom(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);
Error::custom(format_args!(
"unknown variant `{}`, expected one of {:?}",
variant_name,
ExpectedValues::from_iter(names)
))
})
}
}
deserializer.deserialize_identifier(VariantVisitor(self.enum_info))
}
}
struct StructVariantVisitor<'a> {
struct_info: &'static StructVariantInfo,
registration: &'a TypeRegistration,
registry: &'a TypeRegistry,
}
impl<'a, 'de> Visitor<'de> for StructVariantVisitor<'a> {
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)
}
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)
}
}
struct TupleVariantVisitor<'a> {
tuple_info: &'static TupleVariantInfo,
registration: &'a TypeRegistration,
registry: &'a TypeRegistry,
}
impl<'a, 'de> Visitor<'de> for TupleVariantVisitor<'a> {
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)
}
}

View file

@ -0,0 +1,70 @@
use core::fmt::{Debug, Display, Formatter};
use serde::de::{Error, Visitor};
use serde::Deserialize;
use std::fmt;
/// 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,45 @@
use crate::serde::de::registration_utils::try_get_registration;
use crate::serde::TypedReflectDeserializer;
use crate::{DynamicList, ListInfo, TypeRegistry};
use core::fmt::Formatter;
use serde::de::{SeqAccess, Visitor};
use std::fmt;
/// A [`Visitor`] for deserializing [`List`] values.
///
/// [`List`]: crate::List
pub(super) struct ListVisitor<'a> {
list_info: &'static ListInfo,
registry: &'a TypeRegistry,
}
impl<'a> ListVisitor<'a> {
pub fn new(list_info: &'static ListInfo, registry: &'a TypeRegistry) -> Self {
Self {
list_info,
registry,
}
}
}
impl<'a, 'de> Visitor<'de> for ListVisitor<'a> {
type Value = DynamicList;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("reflected list value")
}
fn visit_seq<V>(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(registration, self.registry))?
{
list.push_box(value);
}
Ok(list)
}
}

View file

@ -0,0 +1,49 @@
use crate::serde::de::registration_utils::try_get_registration;
use crate::serde::TypedReflectDeserializer;
use crate::{DynamicMap, Map, MapInfo, TypeRegistry};
use core::fmt::Formatter;
use serde::de::{MapAccess, Visitor};
use std::fmt;
/// A [`Visitor`] for deserializing [`Map`] values.
///
/// [`Map`]: crate::Map
pub(super) struct MapVisitor<'a> {
map_info: &'static MapInfo,
registry: &'a TypeRegistry,
}
impl<'a> MapVisitor<'a> {
pub fn new(map_info: &'static MapInfo, registry: &'a TypeRegistry) -> Self {
Self { map_info, registry }
}
}
impl<'a, 'de> Visitor<'de> for MapVisitor<'a> {
type Value = DynamicMap;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("reflected map value")
}
fn visit_map<V>(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(
key_registration,
self.registry,
))? {
let value = map.next_value_seed(TypedReflectDeserializer::new(
value_registration,
self.registry,
))?;
dynamic_map.insert_boxed(key, value);
}
Ok(dynamic_map)
}
}

View file

@ -0,0 +1,515 @@
pub use deserializer::*;
pub use registrations::*;
mod arrays;
mod deserializer;
mod enums;
mod helpers;
mod lists;
mod maps;
mod options;
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 bincode::Options;
use std::any::TypeId;
use std::f32::consts::PI;
use std::ops::RangeInclusive;
use serde::de::DeserializeSeed;
use serde::Deserialize;
use bevy_utils::{HashMap, HashSet};
use crate as bevy_reflect;
use crate::serde::{ReflectDeserializer, ReflectSerializer, TypedReflectDeserializer};
use crate::{
DynamicEnum, FromReflect, PartialReflect, Reflect, ReflectDeserialize, 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::new();
map.insert(64, 32);
let mut set = HashSet::new();
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_ref().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 dynamic_output = bincode::DefaultOptions::new()
.with_fixint_encoding()
.deserialize_seed(deserializer, &input)
.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, 145,
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();
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()));
}
}

View file

@ -0,0 +1,62 @@
use crate::serde::de::registration_utils::try_get_registration;
use crate::serde::TypedReflectDeserializer;
use crate::{DynamicEnum, DynamicTuple, EnumInfo, TypeRegistry, VariantInfo};
use core::fmt::Formatter;
use serde::de::{DeserializeSeed, Error, Visitor};
use std::fmt;
/// A [`Visitor`] for deserializing [`Option`] values.
pub(super) struct OptionVisitor<'a> {
enum_info: &'static EnumInfo,
registry: &'a TypeRegistry,
}
impl<'a> OptionVisitor<'a> {
pub fn new(enum_info: &'static EnumInfo, registry: &'a TypeRegistry) -> Self {
Self {
enum_info,
registry,
}
}
}
impl<'a, 'de> Visitor<'de> for OptionVisitor<'a> {
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(registration, self.registry);
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(Error::custom(format_args!(
"invalid variant, expected `Some` but got `{}`",
info.name()
))),
}
}
}

View file

@ -0,0 +1,15 @@
use crate::{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(|| Error::custom(format_args!("no registration found for type `{ty:?}`")))?;
Ok(registration)
}

View file

@ -0,0 +1,52 @@
use crate::{TypeRegistration, TypeRegistry};
use core::fmt::Formatter;
use serde::de::{DeserializeSeed, Error, Visitor};
use std::fmt;
/// 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(|| {
Error::custom(format_args!("No registration found for `{type_path}`"))
})
}
}
deserializer.deserialize_str(TypeRegistrationVisitor(self.registry))
}
}

View file

@ -0,0 +1,44 @@
use crate::serde::de::registration_utils::try_get_registration;
use crate::serde::TypedReflectDeserializer;
use crate::{DynamicSet, Set, SetInfo, TypeRegistry};
use core::fmt::Formatter;
use serde::de::{SeqAccess, Visitor};
use std::fmt;
/// A [`Visitor`] for deserializing [`Set`] values.
///
/// [`Set`]: crate::Set
pub(super) struct SetVisitor<'a> {
set_info: &'static SetInfo,
registry: &'a TypeRegistry,
}
impl<'a> SetVisitor<'a> {
pub fn new(set_info: &'static SetInfo, registry: &'a TypeRegistry) -> Self {
Self { set_info, registry }
}
}
impl<'a, 'de> Visitor<'de> for SetVisitor<'a> {
type Value = DynamicSet;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("reflected set value")
}
fn visit_seq<V>(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(
value_registration,
self.registry,
))? {
dynamic_set.insert_boxed(value);
}
Ok(dynamic_set)
}
}

View file

@ -0,0 +1,168 @@
use crate::serde::de::helpers::{ExpectedValues, Ident};
use crate::serde::de::registration_utils::try_get_registration;
use crate::serde::{SerializationData, TypedReflectDeserializer};
use crate::{
DynamicStruct, NamedField, StructInfo, StructVariantInfo, TypeRegistration, TypeRegistry,
};
use core::slice::Iter;
use serde::de::{Error, MapAccess, SeqAccess};
/// 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(|| {
Error::custom(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(|| {
Error::custom(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(|| {
Error::custom(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(|| {
Error::custom(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>(
map: &mut V,
info: &'static T,
registration: &TypeRegistration,
registry: &TypeRegistry,
) -> Result<DynamicStruct, V::Error>
where
T: StructLikeInfo,
V: MapAccess<'de>,
{
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);
Error::custom(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(registration, registry))?;
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>(
seq: &mut V,
info: &T,
registration: &TypeRegistration,
registry: &TypeRegistry,
) -> Result<DynamicStruct, V::Error>
where
T: StructLikeInfo,
V: SeqAccess<'de>,
{
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(
try_get_registration(*info.field_at(index)?.ty(), registry)?,
registry,
))?
.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,50 @@
use crate::serde::de::struct_utils::{visit_struct, visit_struct_seq};
use crate::{DynamicStruct, StructInfo, TypeRegistration, TypeRegistry};
use core::fmt::Formatter;
use serde::de::{MapAccess, SeqAccess, Visitor};
use std::fmt;
/// A [`Visitor`] for deserializing [`Struct`] values.
///
/// [`Struct`]: crate::Struct
pub(super) struct StructVisitor<'a> {
struct_info: &'static StructInfo,
registration: &'a TypeRegistration,
registry: &'a TypeRegistry,
}
impl<'a> StructVisitor<'a> {
pub fn new(
struct_info: &'static StructInfo,
registration: &'a TypeRegistration,
registry: &'a TypeRegistry,
) -> Self {
Self {
struct_info,
registration,
registry,
}
}
}
impl<'a, 'de> Visitor<'de> for StructVisitor<'a> {
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)
}
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)
}
}

View file

@ -0,0 +1,49 @@
use crate::serde::de::tuple_utils::visit_tuple;
use crate::{DynamicTupleStruct, TupleStructInfo, TypeRegistration, TypeRegistry};
use core::fmt::Formatter;
use serde::de::{SeqAccess, Visitor};
use std::fmt;
/// A [`Visitor`] for deserializing [`TupleStruct`] values.
///
/// [`TupleStruct`]: crate::TupleStruct
pub(super) struct TupleStructVisitor<'a> {
tuple_struct_info: &'static TupleStructInfo,
registration: &'a TypeRegistration,
registry: &'a TypeRegistry,
}
impl<'a> TupleStructVisitor<'a> {
pub fn new(
tuple_struct_info: &'static TupleStructInfo,
registration: &'a TypeRegistration,
registry: &'a TypeRegistry,
) -> Self {
Self {
tuple_struct_info,
registration,
registry,
}
}
}
impl<'a, 'de> Visitor<'de> for TupleStructVisitor<'a> {
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,
)
.map(DynamicTupleStruct::from)
}
}

View file

@ -0,0 +1,102 @@
use crate::serde::de::registration_utils::try_get_registration;
use crate::serde::{SerializationData, TypedReflectDeserializer};
use crate::{
DynamicTuple, TupleInfo, TupleStructInfo, TupleVariantInfo, TypeRegistration, TypeRegistry,
UnnamedField,
};
use serde::de::{Error, SeqAccess};
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(|| {
Error::custom(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(|| {
Error::custom(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(|| {
Error::custom(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>(
seq: &mut V,
info: &T,
registration: &TypeRegistration,
registry: &TypeRegistry,
) -> Result<DynamicTuple, V::Error>
where
T: TupleLikeInfo,
V: SeqAccess<'de>,
{
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(
try_get_registration(*info.field_at(index)?.ty(), registry)?,
registry,
))?
.ok_or_else(|| Error::invalid_length(index, &len.to_string().as_str()))?;
tuple.insert_boxed(value);
}
Ok(tuple)
}

View file

@ -0,0 +1,43 @@
use crate::serde::de::tuple_utils::visit_tuple;
use crate::{DynamicTuple, TupleInfo, TypeRegistration, TypeRegistry};
use core::fmt::Formatter;
use serde::de::{SeqAccess, Visitor};
use std::fmt;
/// A [`Visitor`] for deserializing [`Tuple`] values.
///
/// [`Tuple`]: crate::Tuple
pub(super) struct TupleVisitor<'a> {
tuple_info: &'static TupleInfo,
registration: &'a TypeRegistration,
registry: &'a TypeRegistry,
}
impl<'a> TupleVisitor<'a> {
pub fn new(
tuple_info: &'static TupleInfo,
registration: &'a TypeRegistration,
registry: &'a TypeRegistry,
) -> Self {
Self {
tuple_info,
registration,
registry,
}
}
}
impl<'a, 'de> Visitor<'de> for TupleVisitor<'a> {
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)
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,29 @@
use crate::serde::TypedReflectSerializer;
use crate::{Array, TypeRegistry};
use serde::ser::SerializeTuple;
use serde::Serialize;
/// A serializer for [`Array`] values.
pub(super) struct ArraySerializer<'a> {
array: &'a dyn Array,
registry: &'a TypeRegistry,
}
impl<'a> ArraySerializer<'a> {
pub fn new(array: &'a dyn Array, registry: &'a TypeRegistry) -> Self {
Self { array, registry }
}
}
impl<'a> Serialize for ArraySerializer<'a> {
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(value, self.registry))?;
}
state.end()
}
}

View file

@ -0,0 +1,123 @@
use crate::serde::TypedReflectSerializer;
use crate::{Enum, TypeInfo, TypeRegistry, VariantInfo, VariantType};
use serde::ser::{Error, SerializeStructVariant, SerializeTupleVariant};
use serde::Serialize;
/// A serializer for [`Enum`] values.
pub(super) struct EnumSerializer<'a> {
enum_value: &'a dyn Enum,
registry: &'a TypeRegistry,
}
impl<'a> EnumSerializer<'a> {
pub fn new(enum_value: &'a dyn Enum, registry: &'a TypeRegistry) -> Self {
Self {
enum_value,
registry,
}
}
}
impl<'a> Serialize for EnumSerializer<'a> {
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(|| {
Error::custom(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(Error::custom(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(|| {
Error::custom(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(Error::custom(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(field.value(), self.registry),
)?;
}
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(field, self.registry))
} else {
serializer.serialize_newtype_variant(
enum_name,
variant_index,
variant_name,
&TypedReflectSerializer::new(field, self.registry),
)
}
}
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(
field.value(),
self.registry,
))?;
}
state.end()
}
}
}
}

View file

@ -0,0 +1,29 @@
use crate::serde::TypedReflectSerializer;
use crate::{List, TypeRegistry};
use serde::ser::SerializeSeq;
use serde::Serialize;
/// A serializer for [`List`] values.
pub(super) struct ListSerializer<'a> {
list: &'a dyn List,
registry: &'a TypeRegistry,
}
impl<'a> ListSerializer<'a> {
pub fn new(list: &'a dyn List, registry: &'a TypeRegistry) -> Self {
Self { list, registry }
}
}
impl<'a> Serialize for ListSerializer<'a> {
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(value, self.registry))?;
}
state.end()
}
}

View file

@ -0,0 +1,32 @@
use crate::serde::TypedReflectSerializer;
use crate::{Map, TypeRegistry};
use serde::ser::SerializeMap;
use serde::Serialize;
/// A serializer for [`Map`] values.
pub(super) struct MapSerializer<'a> {
map: &'a dyn Map,
registry: &'a TypeRegistry,
}
impl<'a> MapSerializer<'a> {
pub fn new(map: &'a dyn Map, registry: &'a TypeRegistry) -> Self {
Self { map, registry }
}
}
impl<'a> Serialize for MapSerializer<'a> {
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(key, self.registry),
&TypedReflectSerializer::new(value, self.registry),
)?;
}
state.end()
}
}

View file

@ -0,0 +1,456 @@
pub use serializable::*;
pub use serializer::*;
mod arrays;
mod enums;
mod lists;
mod maps;
mod serializable;
mod serializer;
mod sets;
mod structs;
mod tuple_structs;
mod tuples;
#[cfg(test)]
mod tests {
use crate::serde::ReflectSerializer;
use crate::{self as bevy_reflect, PartialReflect, Struct};
use crate::{Reflect, ReflectSerialize, TypeRegistry};
use bevy_utils::{HashMap, HashSet};
use ron::extensions::Extensions;
use ron::ser::PrettyConfig;
use serde::Serialize;
use std::f32::consts::PI;
use std::ops::RangeInclusive;
#[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::new();
map.insert(64, 32);
let mut set = HashSet::new();
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 bytes = bincode::serialize(&serializer).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,
145, 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.clone_dynamic();
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 = std::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();
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();
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()
)
);
}
}

View file

@ -0,0 +1,66 @@
use crate::{PartialReflect, ReflectSerialize, TypeRegistry};
use serde::ser::Error;
use std::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> Serializable<'a> {
/// Attempts to create a [`Serializable`] from a [`PartialReflect`] value.
///
/// Returns an error if any of the following conditions are met:
/// - The underlying type of `value` does not implement [`Reflect`].
/// - The underlying type of `value` does not represent any type (via [`PartialReflect::get_represented_type_info`]).
/// - The represented type of `value` is not registered in the `type_registry`.
/// - The represented type of `value` did not register the [`ReflectSerialize`] type data.
///
/// [`Reflect`]: crate::Reflect
pub fn try_from_reflect_value<E: Error>(
value: &'a dyn PartialReflect,
type_registry: &TypeRegistry,
) -> Result<Serializable<'a>, E> {
let value = value.try_as_reflect().ok_or_else(|| {
Error::custom(format_args!(
"Type '{}' does not implement `Reflect`",
value.reflect_type_path()
))
})?;
let info = value.get_represented_type_info().ok_or_else(|| {
Error::custom(format_args!(
"Type '{}' does not represent any type",
value.reflect_type_path(),
))
})?;
let registration = type_registry.get(info.type_id()).ok_or_else(|| {
Error::custom(format_args!(
"Type `{}` is not registered in the type registry",
info.type_path(),
))
})?;
let reflect_serialize = registration.data::<ReflectSerialize>().ok_or_else(|| {
Error::custom(format_args!(
"Type `{}` did not register the `ReflectSerialize` type data. For certain types, this may need to be registered manually using `register_type_data`",
info.type_path(),
))
})?;
Ok(reflect_serialize.get_serializable(value))
}
}
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,179 @@
use crate::serde::ser::arrays::ArraySerializer;
use crate::serde::ser::enums::EnumSerializer;
use crate::serde::ser::lists::ListSerializer;
use crate::serde::ser::maps::MapSerializer;
use crate::serde::ser::sets::SetSerializer;
use crate::serde::ser::structs::StructSerializer;
use crate::serde::ser::tuple_structs::TupleStructSerializer;
use crate::serde::ser::tuples::TupleSerializer;
use crate::serde::Serializable;
use crate::{PartialReflect, ReflectRef, TypeRegistry};
use serde::ser::{Error, SerializeMap};
use serde::Serialize;
/// 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.
///
/// # 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
pub struct ReflectSerializer<'a> {
value: &'a dyn PartialReflect,
registry: &'a TypeRegistry,
}
impl<'a> ReflectSerializer<'a> {
pub fn new(value: &'a dyn PartialReflect, registry: &'a TypeRegistry) -> Self {
ReflectSerializer { value, registry }
}
}
impl<'a> Serialize for ReflectSerializer<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::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() {
Error::custom(format_args!(
"cannot serialize dynamic value without represented type: {}",
self.value.reflect_type_path()
))
} else {
Error::custom(format_args!(
"cannot get type info for {}",
self.value.reflect_type_path()
))
}
})?
.type_path(),
&TypedReflectSerializer::new(self.value, self.registry),
)?;
state.end()
}
}
/// A serializer for reflected types whose type will be known during deserialization.
///
/// This is the serializer counterpart to [`TypedReflectDeserializer`].
///
/// See [`ReflectSerializer`] for a serializer that serializes an unknown type.
///
/// # Output
///
/// Since the type is expected to be known during deserialization,
/// this serializer will not output any additional type information,
/// such as the [type path].
///
/// Instead, it will output just the serialized data.
///
/// # Example
///
/// ```
/// # use bevy_reflect::prelude::*;
/// # use bevy_reflect::{TypeRegistry, serde::TypedReflectSerializer};
/// #[derive(Reflect, PartialEq, Debug)]
/// #[type_path = "my_crate"]
/// struct MyStruct {
/// value: i32
/// }
///
/// let mut registry = TypeRegistry::default();
/// registry.register::<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
pub struct TypedReflectSerializer<'a> {
value: &'a dyn PartialReflect,
registry: &'a TypeRegistry,
}
impl<'a> TypedReflectSerializer<'a> {
pub fn new(value: &'a dyn PartialReflect, registry: &'a TypeRegistry) -> Self {
TypedReflectSerializer { value, registry }
}
}
impl<'a> Serialize for TypedReflectSerializer<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
// Handle both Value case and types that have a custom `Serialize`
let serializable =
Serializable::try_from_reflect_value::<S::Error>(self.value, self.registry);
if let Ok(serializable) = serializable {
return serializable.serialize(serializer);
}
match self.value.reflect_ref() {
ReflectRef::Struct(value) => {
StructSerializer::new(value, self.registry).serialize(serializer)
}
ReflectRef::TupleStruct(value) => {
TupleStructSerializer::new(value, self.registry).serialize(serializer)
}
ReflectRef::Tuple(value) => {
TupleSerializer::new(value, self.registry).serialize(serializer)
}
ReflectRef::List(value) => {
ListSerializer::new(value, self.registry).serialize(serializer)
}
ReflectRef::Array(value) => {
ArraySerializer::new(value, self.registry).serialize(serializer)
}
ReflectRef::Map(value) => {
MapSerializer::new(value, self.registry).serialize(serializer)
}
ReflectRef::Set(value) => {
SetSerializer::new(value, self.registry).serialize(serializer)
}
ReflectRef::Enum(value) => {
EnumSerializer::new(value, self.registry).serialize(serializer)
}
ReflectRef::Value(_) => Err(serializable.err().unwrap()),
}
}
}

View file

@ -0,0 +1,29 @@
use crate::serde::TypedReflectSerializer;
use crate::{Set, TypeRegistry};
use serde::ser::SerializeSeq;
use serde::Serialize;
/// A serializer for [`Set`] values.
pub(super) struct SetSerializer<'a> {
set: &'a dyn Set,
registry: &'a TypeRegistry,
}
impl<'a> SetSerializer<'a> {
pub fn new(set: &'a dyn Set, registry: &'a TypeRegistry) -> Self {
Self { set, registry }
}
}
impl<'a> Serialize for SetSerializer<'a> {
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(value, self.registry))?;
}
state.end()
}
}

View file

@ -0,0 +1,67 @@
use crate::serde::{SerializationData, TypedReflectSerializer};
use crate::{Struct, TypeInfo, TypeRegistry};
use serde::ser::{Error, SerializeStruct};
use serde::Serialize;
/// A serializer for [`Struct`] values.
pub(super) struct StructSerializer<'a> {
struct_value: &'a dyn Struct,
registry: &'a TypeRegistry,
}
impl<'a> StructSerializer<'a> {
pub fn new(struct_value: &'a dyn Struct, registry: &'a TypeRegistry) -> Self {
Self {
struct_value,
registry,
}
}
}
impl<'a> Serialize for StructSerializer<'a> {
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(|| {
Error::custom(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(Error::custom(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
.map(|data| data.is_field_skipped(index))
.unwrap_or(false)
{
continue;
}
let key = struct_info.field_at(index).unwrap().name();
state.serialize_field(key, &TypedReflectSerializer::new(value, self.registry))?;
}
state.end()
}
}

View file

@ -0,0 +1,66 @@
use crate::serde::{SerializationData, TypedReflectSerializer};
use crate::{TupleStruct, TypeInfo, TypeRegistry};
use serde::ser::{Error, SerializeTupleStruct};
use serde::Serialize;
/// A serializer for [`TupleStruct`] values.
pub(super) struct TupleStructSerializer<'a> {
tuple_struct: &'a dyn TupleStruct,
registry: &'a TypeRegistry,
}
impl<'a> TupleStructSerializer<'a> {
pub fn new(tuple_struct: &'a dyn TupleStruct, registry: &'a TypeRegistry) -> Self {
Self {
tuple_struct,
registry,
}
}
}
impl<'a> Serialize for TupleStructSerializer<'a> {
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(|| {
Error::custom(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(Error::custom(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);
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
.map(|data| data.is_field_skipped(index))
.unwrap_or(false)
{
continue;
}
state.serialize_field(&TypedReflectSerializer::new(value, self.registry))?;
}
state.end()
}
}

View file

@ -0,0 +1,30 @@
use crate::serde::TypedReflectSerializer;
use crate::{Tuple, TypeRegistry};
use serde::ser::SerializeTuple;
use serde::Serialize;
/// A serializer for [`Tuple`] values.
pub(super) struct TupleSerializer<'a> {
tuple: &'a dyn Tuple,
registry: &'a TypeRegistry,
}
impl<'a> TupleSerializer<'a> {
pub fn new(tuple: &'a dyn Tuple, registry: &'a TypeRegistry) -> Self {
Self { tuple, registry }
}
}
impl<'a> Serialize for TupleSerializer<'a> {
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(value, self.registry))?;
}
state.end()
}
}