From ba3d9b3fb6a4ef9b1835146d73fab30c5385f8e4 Mon Sep 17 00:00:00 2001 From: Gino Valente <49806985+MrGVSV@users.noreply.github.com> Date: Mon, 9 Sep 2024 07:03:42 -0700 Subject: [PATCH] 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) --- crates/bevy_reflect/src/serde/de.rs | 1712 ----------------- crates/bevy_reflect/src/serde/de/arrays.rs | 53 + .../bevy_reflect/src/serde/de/deserializer.rs | 333 ++++ crates/bevy_reflect/src/serde/de/enums.rs | 198 ++ crates/bevy_reflect/src/serde/de/helpers.rs | 70 + crates/bevy_reflect/src/serde/de/lists.rs | 45 + crates/bevy_reflect/src/serde/de/maps.rs | 49 + crates/bevy_reflect/src/serde/de/mod.rs | 515 +++++ crates/bevy_reflect/src/serde/de/options.rs | 62 + .../src/serde/de/registration_utils.rs | 15 + .../src/serde/de/registrations.rs | 52 + crates/bevy_reflect/src/serde/de/sets.rs | 44 + .../bevy_reflect/src/serde/de/struct_utils.rs | 168 ++ crates/bevy_reflect/src/serde/de/structs.rs | 50 + .../src/serde/de/tuple_structs.rs | 49 + .../bevy_reflect/src/serde/de/tuple_utils.rs | 102 + crates/bevy_reflect/src/serde/de/tuples.rs | 43 + crates/bevy_reflect/src/serde/ser.rs | 1012 ---------- crates/bevy_reflect/src/serde/ser/arrays.rs | 29 + crates/bevy_reflect/src/serde/ser/enums.rs | 123 ++ crates/bevy_reflect/src/serde/ser/lists.rs | 29 + crates/bevy_reflect/src/serde/ser/maps.rs | 32 + crates/bevy_reflect/src/serde/ser/mod.rs | 456 +++++ .../src/serde/ser/serializable.rs | 66 + .../bevy_reflect/src/serde/ser/serializer.rs | 179 ++ crates/bevy_reflect/src/serde/ser/sets.rs | 29 + crates/bevy_reflect/src/serde/ser/structs.rs | 67 + .../src/serde/ser/tuple_structs.rs | 66 + crates/bevy_reflect/src/serde/ser/tuples.rs | 30 + 29 files changed, 2954 insertions(+), 2724 deletions(-) delete mode 100644 crates/bevy_reflect/src/serde/de.rs create mode 100644 crates/bevy_reflect/src/serde/de/arrays.rs create mode 100644 crates/bevy_reflect/src/serde/de/deserializer.rs create mode 100644 crates/bevy_reflect/src/serde/de/enums.rs create mode 100644 crates/bevy_reflect/src/serde/de/helpers.rs create mode 100644 crates/bevy_reflect/src/serde/de/lists.rs create mode 100644 crates/bevy_reflect/src/serde/de/maps.rs create mode 100644 crates/bevy_reflect/src/serde/de/mod.rs create mode 100644 crates/bevy_reflect/src/serde/de/options.rs create mode 100644 crates/bevy_reflect/src/serde/de/registration_utils.rs create mode 100644 crates/bevy_reflect/src/serde/de/registrations.rs create mode 100644 crates/bevy_reflect/src/serde/de/sets.rs create mode 100644 crates/bevy_reflect/src/serde/de/struct_utils.rs create mode 100644 crates/bevy_reflect/src/serde/de/structs.rs create mode 100644 crates/bevy_reflect/src/serde/de/tuple_structs.rs create mode 100644 crates/bevy_reflect/src/serde/de/tuple_utils.rs create mode 100644 crates/bevy_reflect/src/serde/de/tuples.rs delete mode 100644 crates/bevy_reflect/src/serde/ser.rs create mode 100644 crates/bevy_reflect/src/serde/ser/arrays.rs create mode 100644 crates/bevy_reflect/src/serde/ser/enums.rs create mode 100644 crates/bevy_reflect/src/serde/ser/lists.rs create mode 100644 crates/bevy_reflect/src/serde/ser/maps.rs create mode 100644 crates/bevy_reflect/src/serde/ser/mod.rs create mode 100644 crates/bevy_reflect/src/serde/ser/serializable.rs create mode 100644 crates/bevy_reflect/src/serde/ser/serializer.rs create mode 100644 crates/bevy_reflect/src/serde/ser/sets.rs create mode 100644 crates/bevy_reflect/src/serde/ser/structs.rs create mode 100644 crates/bevy_reflect/src/serde/ser/tuple_structs.rs create mode 100644 crates/bevy_reflect/src/serde/ser/tuples.rs diff --git a/crates/bevy_reflect/src/serde/de.rs b/crates/bevy_reflect/src/serde/de.rs deleted file mode 100644 index 5563d9192f..0000000000 --- a/crates/bevy_reflect/src/serde/de.rs +++ /dev/null @@ -1,1712 +0,0 @@ -use crate::serde::SerializationData; -use crate::{ - ArrayInfo, DynamicArray, DynamicEnum, DynamicList, DynamicMap, DynamicSet, DynamicStruct, - DynamicTuple, DynamicTupleStruct, DynamicVariant, EnumInfo, ListInfo, Map, MapInfo, NamedField, - PartialReflect, Reflect, ReflectDeserialize, Set, SetInfo, StructInfo, StructVariantInfo, - TupleInfo, TupleStructInfo, TupleVariantInfo, TypeInfo, TypeRegistration, TypeRegistry, - VariantInfo, -}; -use erased_serde::Deserializer; -use serde::de::{ - DeserializeSeed, EnumAccess, Error, IgnoredAny, MapAccess, SeqAccess, VariantAccess, Visitor, -}; -use serde::Deserialize; -use std::any::TypeId; -use std::fmt; -use std::fmt::{Debug, Display, Formatter}; -use std::slice::Iter; - -pub trait DeserializeValue { - fn deserialize( - deserializer: &mut dyn Deserializer, - type_registry: &TypeRegistry, - ) -> Result, erased_serde::Error>; -} - -trait StructLikeInfo { - fn get_field(&self, name: &str) -> Option<&NamedField>; - fn field_at(&self, index: usize) -> Option<&NamedField>; - fn get_field_len(&self) -> usize; - fn iter_fields(&self) -> Iter<'_, NamedField>; -} - -trait TupleLikeInfo { - fn get_field_len(&self) -> usize; -} - -trait Container { - fn get_field_registration<'a, E: Error>( - &self, - index: usize, - registry: &'a TypeRegistry, - ) -> Result<&'a TypeRegistration, E>; -} - -impl StructLikeInfo for StructInfo { - fn get_field(&self, name: &str) -> Option<&NamedField> { - self.field(name) - } - - fn field_at(&self, index: usize) -> Option<&NamedField> { - self.field_at(index) - } - - fn get_field_len(&self) -> usize { - self.field_len() - } - - fn iter_fields(&self) -> Iter<'_, NamedField> { - self.iter() - } -} - -impl Container for StructInfo { - fn get_field_registration<'a, E: Error>( - &self, - index: usize, - registry: &'a TypeRegistry, - ) -> Result<&'a TypeRegistration, E> { - let field = self.field_at(index).ok_or_else(|| { - Error::custom(format_args!( - "no field at index {} on struct {}", - index, - self.type_path(), - )) - })?; - get_registration(field.type_id(), field.type_path(), registry) - } -} - -impl StructLikeInfo for StructVariantInfo { - fn get_field(&self, name: &str) -> Option<&NamedField> { - self.field(name) - } - - fn field_at(&self, index: usize) -> Option<&NamedField> { - self.field_at(index) - } - - fn get_field_len(&self) -> usize { - self.field_len() - } - - fn iter_fields(&self) -> Iter<'_, NamedField> { - self.iter() - } -} - -impl Container for StructVariantInfo { - fn get_field_registration<'a, E: Error>( - &self, - index: usize, - registry: &'a TypeRegistry, - ) -> Result<&'a TypeRegistration, E> { - let field = self.field_at(index).ok_or_else(|| { - Error::custom(format_args!( - "no field at index {} on variant {}", - index, - self.name(), - )) - })?; - get_registration(field.type_id(), field.type_path(), registry) - } -} - -impl TupleLikeInfo for TupleInfo { - fn get_field_len(&self) -> usize { - self.field_len() - } -} - -impl Container for TupleInfo { - fn get_field_registration<'a, E: Error>( - &self, - index: usize, - registry: &'a TypeRegistry, - ) -> Result<&'a TypeRegistration, E> { - let field = self.field_at(index).ok_or_else(|| { - Error::custom(format_args!( - "no field at index {} on tuple {}", - index, - self.type_path(), - )) - })?; - get_registration(field.type_id(), field.type_path(), registry) - } -} - -impl TupleLikeInfo for TupleStructInfo { - fn get_field_len(&self) -> usize { - self.field_len() - } -} - -impl Container for TupleStructInfo { - fn get_field_registration<'a, E: Error>( - &self, - index: usize, - registry: &'a TypeRegistry, - ) -> Result<&'a TypeRegistration, E> { - let field = self.field_at(index).ok_or_else(|| { - Error::custom(format_args!( - "no field at index {} on tuple struct {}", - index, - self.type_path(), - )) - })?; - get_registration(field.type_id(), field.type_path(), registry) - } -} - -impl TupleLikeInfo for TupleVariantInfo { - fn get_field_len(&self) -> usize { - self.field_len() - } -} - -impl Container for TupleVariantInfo { - fn get_field_registration<'a, E: Error>( - &self, - index: usize, - registry: &'a TypeRegistry, - ) -> Result<&'a TypeRegistration, E> { - let field = self.field_at(index).ok_or_else(|| { - Error::custom(format_args!( - "no field at index {} on tuple variant {}", - index, - self.name(), - )) - })?; - get_registration(field.type_id(), field.type_path(), registry) - } -} - -/// 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))); -/// ``` -struct ExpectedValues(Vec); - -impl Debug for ExpectedValues { - 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)] -struct Ident(String); - -impl<'de> Deserialize<'de> for Ident { - fn deserialize(deserializer: D) -> Result - 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(self, value: &str) -> Result - where - E: Error, - { - Ok(Ident(value.to_string())) - } - - fn visit_string(self, value: String) -> Result - where - E: Error, - { - Ok(Ident(value)) - } - } - - deserializer.deserialize_identifier(IdentVisitor) - } -} - -/// 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(self, deserializer: D) -> Result - 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(self, type_path: &str) -> Result - 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)) - } -} - -/// A general purpose deserializer for reflected types. -/// -/// This is the deserializer counterpart to [`ReflectSerializer`]. -/// -/// See [`TypedReflectDeserializer`] for a deserializer that expects a known type. -/// -/// # Input -/// -/// This deserializer expects a map with a single entry, -/// where the key is the _full_ [type path] of the reflected type -/// and the value is the serialized data. -/// -/// # Output -/// -/// This deserializer will return a [`Box`] containing the deserialized data. -/// -/// For value types (i.e. [`ReflectKind::Value`]) or types that register [`ReflectDeserialize`] type data, -/// this `Box` will contain the expected type. -/// For example, deserializing an `i32` will return a `Box` (as a `Box`). -/// -/// Otherwise, this `Box` will contain the dynamic equivalent. -/// For example, a deserialized struct might return a [`Box`] -/// and a deserialized `Vec` might return a [`Box`]. -/// -/// This means that if the actual type is needed, these dynamic representations will need to -/// be converted to the concrete type using [`FromReflect`] or [`ReflectFromReflect`]. -/// -/// # Example -/// -/// ``` -/// # use serde::de::DeserializeSeed; -/// # use bevy_reflect::prelude::*; -/// # use bevy_reflect::{DynamicStruct, TypeRegistry, serde::ReflectDeserializer}; -/// #[derive(Reflect, PartialEq, Debug)] -/// #[type_path = "my_crate"] -/// struct MyStruct { -/// value: i32 -/// } -/// -/// let mut registry = TypeRegistry::default(); -/// registry.register::(); -/// -/// let input = r#"{ -/// "my_crate::MyStruct": ( -/// value: 123 -/// ) -/// }"#; -/// -/// let mut deserializer = ron::Deserializer::from_str(input).unwrap(); -/// let reflect_deserializer = ReflectDeserializer::new(®istry); -/// -/// let output: Box = reflect_deserializer.deserialize(&mut deserializer).unwrap(); -/// -/// // Since `MyStruct` is not a value type and does not register `ReflectDeserialize`, -/// // we know that its deserialized value will be a `DynamicStruct`, -/// // although it will represent `MyStruct`. -/// assert!(output.as_partial_reflect().represents::()); -/// -/// // We can convert back to `MyStruct` using `FromReflect`. -/// let value: MyStruct = ::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::(type_id).unwrap(); -/// let value: Box = reflect_from_reflect.from_reflect(output.as_partial_reflect()).unwrap(); -/// assert!(value.is::()); -/// assert_eq!(value.take::().unwrap(), MyStruct { value: 123 }); -/// ``` -/// -/// [`ReflectSerializer`]: crate::serde::ReflectSerializer -/// [type path]: crate::TypePath::type_path -/// [`Box`]: crate::Reflect -/// [`ReflectKind::Value`]: crate::ReflectKind::Value -/// [`ReflectDeserialize`]: crate::ReflectDeserialize -/// [`Box`]: crate::DynamicStruct -/// [`Box`]: crate::DynamicList -/// [`FromReflect`]: crate::FromReflect -/// [`ReflectFromReflect`]: crate::ReflectFromReflect -pub struct ReflectDeserializer<'a> { - registry: &'a TypeRegistry, -} - -impl<'a> ReflectDeserializer<'a> { - pub fn new(registry: &'a TypeRegistry) -> Self { - Self { registry } - } -} - -impl<'a, 'de> DeserializeSeed<'de> for ReflectDeserializer<'a> { - type Value = Box; - - fn deserialize(self, deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - struct UntypedReflectDeserializerVisitor<'a> { - registry: &'a TypeRegistry, - } - - impl<'a, 'de> Visitor<'de> for UntypedReflectDeserializerVisitor<'a> { - type Value = Box; - - fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { - formatter - .write_str("map containing `type` and `value` entries for the reflected value") - } - - fn visit_map(self, mut map: A) -> Result - where - A: MapAccess<'de>, - { - let registration = map - .next_key_seed(TypeRegistrationDeserializer::new(self.registry))? - .ok_or_else(|| Error::invalid_length(0, &"a single entry"))?; - - let value = map.next_value_seed(TypedReflectDeserializer { - registration, - registry: self.registry, - })?; - - if map.next_key::()?.is_some() { - return Err(Error::invalid_length(2, &"a single entry")); - } - - 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`] containing the deserialized data. -/// -/// For value types (i.e. [`ReflectKind::Value`]) or types that register [`ReflectDeserialize`] type data, -/// this `Box` will contain the expected type. -/// For example, deserializing an `i32` will return a `Box` (as a `Box`). -/// -/// Otherwise, this `Box` will contain the dynamic equivalent. -/// For example, a deserialized struct might return a [`Box`] -/// and a deserialized `Vec` might return a [`Box`]. -/// -/// This means that if the actual type is needed, these dynamic representations will need to -/// be converted to the concrete type using [`FromReflect`] or [`ReflectFromReflect`]. -/// -/// # Example -/// -/// ``` -/// # use std::any::TypeId; -/// # use serde::de::DeserializeSeed; -/// # use bevy_reflect::prelude::*; -/// # use bevy_reflect::{DynamicStruct, TypeRegistry, serde::TypedReflectDeserializer}; -/// #[derive(Reflect, PartialEq, Debug)] -/// struct MyStruct { -/// value: i32 -/// } -/// -/// let mut registry = TypeRegistry::default(); -/// registry.register::(); -/// -/// let input = r#"( -/// value: 123 -/// )"#; -/// -/// let registration = registry.get(TypeId::of::()).unwrap(); -/// -/// let mut deserializer = ron::Deserializer::from_str(input).unwrap(); -/// let reflect_deserializer = TypedReflectDeserializer::new(registration, ®istry); -/// -/// let output: Box = reflect_deserializer.deserialize(&mut deserializer).unwrap(); -/// -/// // Since `MyStruct` is not a value type and does not register `ReflectDeserialize`, -/// // we know that its deserialized value will be a `DynamicStruct`, -/// // although it will represent `MyStruct`. -/// assert!(output.as_partial_reflect().represents::()); -/// -/// // We can convert back to `MyStruct` using `FromReflect`. -/// let value: MyStruct = ::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::(type_id).unwrap(); -/// let value: Box = reflect_from_reflect.from_reflect(output.as_partial_reflect()).unwrap(); -/// assert!(value.is::()); -/// assert_eq!(value.take::().unwrap(), MyStruct { value: 123 }); -/// ``` -/// -/// [`TypedReflectSerializer`]: crate::serde::TypedReflectSerializer -/// [`Box`]: crate::Reflect -/// [`ReflectKind::Value`]: crate::ReflectKind::Value -/// [`ReflectDeserialize`]: crate::ReflectDeserialize -/// [`Box`]: crate::DynamicStruct -/// [`Box`]: crate::DynamicList -/// [`FromReflect`]: crate::FromReflect -/// [`ReflectFromReflect`]: crate::ReflectFromReflect -pub struct TypedReflectDeserializer<'a> { - registration: &'a TypeRegistration, - registry: &'a TypeRegistry, -} - -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; - - fn deserialize(self, deserializer: D) -> Result - 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::() { - 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 { - struct_info, - registration: self.registration, - registry: 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 { - tuple_struct_info, - registry: self.registry, - registration: self.registration, - }, - )?; - 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, - })?; - 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, - }, - )?; - 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, - })?; - 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, - })?; - 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, - }, - )?; - 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, - })? - } else { - deserializer.deserialize_enum( - enum_info.type_path_table().ident().unwrap(), - enum_info.variant_names(), - EnumVisitor { - enum_info, - registration: self.registration, - registry: 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`", - ))) - } - } - } -} - -struct StructVisitor<'a> { - struct_info: &'static StructInfo, - registration: &'a TypeRegistration, - registry: &'a TypeRegistry, -} - -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(self, mut seq: A) -> Result - where - A: SeqAccess<'de>, - { - visit_struct_seq(&mut seq, self.struct_info, self.registration, self.registry) - } - - fn visit_map(self, mut map: V) -> Result - where - V: MapAccess<'de>, - { - visit_struct(&mut map, self.struct_info, self.registration, self.registry) - } -} - -struct TupleStructVisitor<'a> { - tuple_struct_info: &'static TupleStructInfo, - registry: &'a TypeRegistry, - registration: &'a TypeRegistration, -} - -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(self, mut seq: V) -> Result - where - V: SeqAccess<'de>, - { - visit_tuple( - &mut seq, - self.tuple_struct_info, - self.registration, - self.registry, - ) - .map(DynamicTupleStruct::from) - } -} - -struct TupleVisitor<'a> { - tuple_info: &'static TupleInfo, - registration: &'a TypeRegistration, - registry: &'a TypeRegistry, -} - -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(self, mut seq: V) -> Result - where - V: SeqAccess<'de>, - { - visit_tuple(&mut seq, self.tuple_info, self.registration, self.registry) - } -} - -struct ArrayVisitor<'a> { - array_info: &'static ArrayInfo, - registry: &'a TypeRegistry, -} - -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(self, mut seq: V) -> Result - where - V: SeqAccess<'de>, - { - let mut vec = Vec::with_capacity(seq.size_hint().unwrap_or_default()); - let registration = get_registration( - self.array_info.item_ty().id(), - self.array_info.item_ty().path(), - self.registry, - )?; - while let Some(value) = seq.next_element_seed(TypedReflectDeserializer { - registration, - registry: 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())) - } -} - -struct ListVisitor<'a> { - list_info: &'static ListInfo, - registry: &'a TypeRegistry, -} - -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(self, mut seq: V) -> Result - where - V: SeqAccess<'de>, - { - let mut list = DynamicList::default(); - let registration = get_registration( - self.list_info.item_ty().id(), - self.list_info.item_ty().path(), - self.registry, - )?; - while let Some(value) = seq.next_element_seed(TypedReflectDeserializer { - registration, - registry: self.registry, - })? { - list.push_box(value); - } - Ok(list) - } -} - -struct MapVisitor<'a> { - map_info: &'static MapInfo, - registry: &'a TypeRegistry, -} - -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(self, mut map: V) -> Result - where - V: MapAccess<'de>, - { - let mut dynamic_map = DynamicMap::default(); - let key_registration = get_registration( - self.map_info.key_ty().id(), - self.map_info.key_ty().path(), - self.registry, - )?; - let value_registration = get_registration( - self.map_info.value_ty().id(), - self.map_info.value_ty().path(), - self.registry, - )?; - while let Some(key) = map.next_key_seed(TypedReflectDeserializer { - registration: key_registration, - registry: self.registry, - })? { - let value = map.next_value_seed(TypedReflectDeserializer { - registration: value_registration, - registry: self.registry, - })?; - dynamic_map.insert_boxed(key, value); - } - - Ok(dynamic_map) - } -} - -struct SetVisitor<'a> { - set_info: &'static SetInfo, - registry: &'a TypeRegistry, -} - -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(self, mut set: V) -> Result - where - V: SeqAccess<'de>, - { - let mut dynamic_set = DynamicSet::default(); - let value_registration = get_registration( - self.set_info.value_ty().id(), - self.set_info.value_ty().path(), - self.registry, - )?; - while let Some(value) = set.next_element_seed(TypedReflectDeserializer { - registration: value_registration, - registry: self.registry, - })? { - dynamic_set.insert_boxed(value); - } - - Ok(dynamic_set) - } -} - -struct EnumVisitor<'a> { - enum_info: &'static EnumInfo, - registration: &'a TypeRegistration, - registry: &'a TypeRegistry, -} - -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(self, data: A) -> Result - 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 = tuple_info.get_field_registration(0, self.registry)?; - let value = variant.newtype_variant_seed(TypedReflectDeserializer { - registration, - registry: 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(self, deserializer: D) -> Result - 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(self, variant_index: u32) -> Result - 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(self, variant_name: &str) -> Result - 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(names.collect()) - )) - }) - } - } - - 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(self, mut seq: A) -> Result - where - A: SeqAccess<'de>, - { - visit_struct_seq(&mut seq, self.struct_info, self.registration, self.registry) - } - - fn visit_map(self, mut map: V) -> Result - 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(self, mut seq: V) -> Result - where - V: SeqAccess<'de>, - { - visit_tuple(&mut seq, self.tuple_info, self.registration, self.registry) - } -} - -struct OptionVisitor<'a> { - enum_info: &'static EnumInfo, - registry: &'a TypeRegistry, -} - -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(self) -> Result - where - E: Error, - { - let mut option = DynamicEnum::default(); - option.set_variant("None", ()); - Ok(option) - } - - fn visit_some(self, deserializer: D) -> Result - 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 = - get_registration(field.type_id(), field.type_path(), self.registry)?; - let de = TypedReflectDeserializer { - registration, - registry: 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() - ))), - } - } -} - -fn visit_struct<'de, T, V>( - map: &mut V, - info: &'static T, - registration: &TypeRegistration, - registry: &TypeRegistry, -) -> Result -where - T: StructLikeInfo, - V: MapAccess<'de>, -{ - let mut dynamic_struct = DynamicStruct::default(); - while let Some(Ident(key)) = map.next_key::()? { - let field = info.get_field(&key).ok_or_else(|| { - let fields = info.iter_fields().map(NamedField::name); - Error::custom(format_args!( - "unknown field `{}`, expected one of {:?}", - key, - ExpectedValues(fields.collect()) - )) - })?; - let registration = get_registration(field.type_id(), field.type_path(), registry)?; - let value = map.next_value_seed(TypedReflectDeserializer { - registration, - registry, - })?; - dynamic_struct.insert_boxed(&key, value); - } - - if let Some(serialization_data) = registration.data::() { - for (skipped_index, skipped_field) in serialization_data.iter_skipped() { - let Some(field) = info.field_at(*skipped_index) else { - continue; - }; - dynamic_struct.insert_boxed( - field.name(), - skipped_field.generate_default().into_partial_reflect(), - ); - } - } - - Ok(dynamic_struct) -} - -fn visit_tuple<'de, T, V>( - seq: &mut V, - info: &T, - registration: &TypeRegistration, - registry: &TypeRegistry, -) -> Result -where - T: TupleLikeInfo + Container, - V: SeqAccess<'de>, -{ - let mut tuple = DynamicTuple::default(); - - let len = info.get_field_len(); - - if len == 0 { - // Handle empty tuple/tuple struct - return Ok(tuple); - } - - let serialization_data = registration.data::(); - - 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 { - registration: info.get_field_registration(index, registry)?, - registry, - })? - .ok_or_else(|| Error::invalid_length(index, &len.to_string().as_str()))?; - tuple.insert_boxed(value); - } - - Ok(tuple) -} - -fn visit_struct_seq<'de, T, V>( - seq: &mut V, - info: &T, - registration: &TypeRegistration, - registry: &TypeRegistry, -) -> Result -where - T: StructLikeInfo + Container, - V: SeqAccess<'de>, -{ - let mut dynamic_struct = DynamicStruct::default(); - - let len = info.get_field_len(); - - if len == 0 { - // Handle unit structs - return Ok(dynamic_struct); - } - - let serialization_data = registration.data::(); - - for index in 0..len { - let name = info.field_at(index).unwrap().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 { - registration: info.get_field_registration(index, registry)?, - registry, - })? - .ok_or_else(|| Error::invalid_length(index, &len.to_string().as_str()))?; - dynamic_struct.insert_boxed(name, value); - } - - Ok(dynamic_struct) -} - -fn get_registration<'a, E: Error>( - type_id: TypeId, - type_path: &str, - registry: &'a TypeRegistry, -) -> Result<&'a TypeRegistration, E> { - let registration = registry.get(type_id).ok_or_else(|| { - Error::custom(format_args!("no registration found for type `{type_path}`")) - })?; - Ok(registration) -} - -#[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, - option_value_complex: Option, - tuple_value: (f32, usize), - list_value: Vec, - array_value: [i32; 5], - map_value: HashMap, - set_value: HashSet, - 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::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::<(f32, usize)>(); - registry.register::<[i32; 5]>(); - registry.register::>(); - registry.register::>(); - registry.register::>(); - registry.register::>(); - registry.register::>(); - registry.register_type_data::, 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(®istry); - let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap(); - let dynamic_output = reflect_deserializer - .deserialize(&mut ron_deserializer) - .unwrap(); - - let output = ::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(®istry); - 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::() - .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::(); - let registration = registry.get(TypeId::of::()).unwrap(); - let reflect_deserializer = TypedReflectDeserializer::new(registration, ®istry); - let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap(); - let dynamic_output = reflect_deserializer - .deserialize(&mut ron_deserializer) - .unwrap(); - - let output = - ::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, - complex: Option, - } - - let expected = OptionTest { - none: None, - simple: Some(String::from("Hello world!")), - complex: Some(SomeStruct { foo: 123 }), - }; - - let mut registry = get_registry(); - registry.register::(); - registry.register::>(); - - // === 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(®istry); - let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap(); - let dynamic_output = reflect_deserializer - .deserialize(&mut ron_deserializer) - .unwrap(); - - let output = ::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(®istry); - let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap(); - let dynamic_output = reflect_deserializer - .deserialize(&mut ron_deserializer) - .unwrap(); - - let output = ::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::(); - - // === Unit Variant === // - let input = r#"{ - "bevy_reflect::serde::de::tests::MyEnum": Unit, -}"#; - let reflect_deserializer = ReflectDeserializer::new(®istry); - 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(®istry); - 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(®istry); - 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(®istry); - 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, ®istry); - let serialized1 = ron::ser::to_string(&serializer1).unwrap(); - - let mut deserializer = ron::de::Deserializer::from_str(&serialized1).unwrap(); - let reflect_deserializer = ReflectDeserializer::new(®istry); - let input2 = reflect_deserializer.deserialize(&mut deserializer).unwrap(); - - let serializer2 = ReflectSerializer::new(input2.as_partial_reflect(), ®istry); - 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(®istry); - - let dynamic_output = bincode::DefaultOptions::new() - .with_fixint_encoding() - .deserialize_seed(deserializer, &input) - .unwrap(); - - let output = ::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(®istry); - let dynamic_output = deserializer - .deserialize(&mut rmp_serde::Deserializer::new(&mut reader)) - .unwrap(); - - let output = ::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::>(); - - let input = r#"{"core::ops::RangeInclusive":(start:0.0,end:1.0)}"#; - let mut deserializer = ron::de::Deserializer::from_str(input).unwrap(); - let reflect_deserializer = ReflectDeserializer::new(®istry); - let error = reflect_deserializer - .deserialize(&mut deserializer) - .unwrap_err(); - assert_eq!(error, ron::Error::Message("Type `core::ops::RangeInclusive` did not register the `ReflectDeserialize` type data. For certain types, this may need to be registered manually using `register_type_data`".to_string())); - } -} diff --git a/crates/bevy_reflect/src/serde/de/arrays.rs b/crates/bevy_reflect/src/serde/de/arrays.rs new file mode 100644 index 0000000000..6e2f331a65 --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/arrays.rs @@ -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(self, mut seq: V) -> Result + 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())) + } +} diff --git a/crates/bevy_reflect/src/serde/de/deserializer.rs b/crates/bevy_reflect/src/serde/de/deserializer.rs new file mode 100644 index 0000000000..a4496dc72d --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/deserializer.rs @@ -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`] containing the deserialized data. +/// +/// For value types (i.e. [`ReflectKind::Value`]) or types that register [`ReflectDeserialize`] type data, +/// this `Box` will contain the expected type. +/// For example, deserializing an `i32` will return a `Box` (as a `Box`). +/// +/// Otherwise, this `Box` will contain the dynamic equivalent. +/// For example, a deserialized struct might return a [`Box`] +/// and a deserialized `Vec` might return a [`Box`]. +/// +/// This means that if the actual type is needed, these dynamic representations will need to +/// be converted to the concrete type using [`FromReflect`] or [`ReflectFromReflect`]. +/// +/// # Example +/// +/// ``` +/// # use serde::de::DeserializeSeed; +/// # use bevy_reflect::prelude::*; +/// # use bevy_reflect::{DynamicStruct, TypeRegistry, serde::ReflectDeserializer}; +/// #[derive(Reflect, PartialEq, Debug)] +/// #[type_path = "my_crate"] +/// struct MyStruct { +/// value: i32 +/// } +/// +/// let mut registry = TypeRegistry::default(); +/// registry.register::(); +/// +/// let input = r#"{ +/// "my_crate::MyStruct": ( +/// value: 123 +/// ) +/// }"#; +/// +/// let mut deserializer = ron::Deserializer::from_str(input).unwrap(); +/// let reflect_deserializer = ReflectDeserializer::new(®istry); +/// +/// let output: Box = reflect_deserializer.deserialize(&mut deserializer).unwrap(); +/// +/// // Since `MyStruct` is not a value type and does not register `ReflectDeserialize`, +/// // we know that its deserialized value will be a `DynamicStruct`, +/// // although it will represent `MyStruct`. +/// assert!(output.as_partial_reflect().represents::()); +/// +/// // We can convert back to `MyStruct` using `FromReflect`. +/// let value: MyStruct = ::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::(type_id).unwrap(); +/// let value: Box = reflect_from_reflect.from_reflect(output.as_partial_reflect()).unwrap(); +/// assert!(value.is::()); +/// assert_eq!(value.take::().unwrap(), MyStruct { value: 123 }); +/// ``` +/// +/// [`ReflectSerializer`]: crate::serde::ReflectSerializer +/// [type path]: crate::TypePath::type_path +/// [`Box`]: crate::Reflect +/// [`ReflectKind::Value`]: crate::ReflectKind::Value +/// [`ReflectDeserialize`]: crate::ReflectDeserialize +/// [`Box`]: crate::DynamicStruct +/// [`Box`]: crate::DynamicList +/// [`FromReflect`]: crate::FromReflect +/// [`ReflectFromReflect`]: crate::ReflectFromReflect +pub struct ReflectDeserializer<'a> { + registry: &'a TypeRegistry, +} + +impl<'a> ReflectDeserializer<'a> { + pub fn new(registry: &'a TypeRegistry) -> Self { + Self { registry } + } +} + +impl<'a, 'de> DeserializeSeed<'de> for ReflectDeserializer<'a> { + type Value = Box; + + fn deserialize(self, deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + struct UntypedReflectDeserializerVisitor<'a> { + registry: &'a TypeRegistry, + } + + impl<'a, 'de> Visitor<'de> for UntypedReflectDeserializerVisitor<'a> { + type Value = Box; + + fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { + formatter + .write_str("map containing `type` and `value` entries for the reflected value") + } + + fn visit_map(self, mut map: A) -> Result + where + A: MapAccess<'de>, + { + let registration = map + .next_key_seed(TypeRegistrationDeserializer::new(self.registry))? + .ok_or_else(|| Error::invalid_length(0, &"a single entry"))?; + + let value = map.next_value_seed(TypedReflectDeserializer { + registration, + registry: self.registry, + })?; + + if map.next_key::()?.is_some() { + return Err(Error::invalid_length(2, &"a single entry")); + } + + 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`] containing the deserialized data. +/// +/// For value types (i.e. [`ReflectKind::Value`]) or types that register [`ReflectDeserialize`] type data, +/// this `Box` will contain the expected type. +/// For example, deserializing an `i32` will return a `Box` (as a `Box`). +/// +/// Otherwise, this `Box` will contain the dynamic equivalent. +/// For example, a deserialized struct might return a [`Box`] +/// and a deserialized `Vec` might return a [`Box`]. +/// +/// This means that if the actual type is needed, these dynamic representations will need to +/// be converted to the concrete type using [`FromReflect`] or [`ReflectFromReflect`]. +/// +/// # Example +/// +/// ``` +/// # use std::any::TypeId; +/// # use serde::de::DeserializeSeed; +/// # use bevy_reflect::prelude::*; +/// # use bevy_reflect::{DynamicStruct, TypeRegistry, serde::TypedReflectDeserializer}; +/// #[derive(Reflect, PartialEq, Debug)] +/// struct MyStruct { +/// value: i32 +/// } +/// +/// let mut registry = TypeRegistry::default(); +/// registry.register::(); +/// +/// let input = r#"( +/// value: 123 +/// )"#; +/// +/// let registration = registry.get(TypeId::of::()).unwrap(); +/// +/// let mut deserializer = ron::Deserializer::from_str(input).unwrap(); +/// let reflect_deserializer = TypedReflectDeserializer::new(registration, ®istry); +/// +/// let output: Box = reflect_deserializer.deserialize(&mut deserializer).unwrap(); +/// +/// // Since `MyStruct` is not a value type and does not register `ReflectDeserialize`, +/// // we know that its deserialized value will be a `DynamicStruct`, +/// // although it will represent `MyStruct`. +/// assert!(output.as_partial_reflect().represents::()); +/// +/// // We can convert back to `MyStruct` using `FromReflect`. +/// let value: MyStruct = ::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::(type_id).unwrap(); +/// let value: Box = reflect_from_reflect.from_reflect(output.as_partial_reflect()).unwrap(); +/// assert!(value.is::()); +/// assert_eq!(value.take::().unwrap(), MyStruct { value: 123 }); +/// ``` +/// +/// [`TypedReflectSerializer`]: crate::serde::TypedReflectSerializer +/// [`Box`]: crate::Reflect +/// [`ReflectKind::Value`]: crate::ReflectKind::Value +/// [`ReflectDeserialize`]: crate::ReflectDeserialize +/// [`Box`]: crate::DynamicStruct +/// [`Box`]: crate::DynamicList +/// [`FromReflect`]: crate::FromReflect +/// [`ReflectFromReflect`]: crate::ReflectFromReflect +pub struct TypedReflectDeserializer<'a> { + registration: &'a TypeRegistration, + registry: &'a TypeRegistry, +} + +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; + + fn deserialize(self, deserializer: D) -> Result + 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::() { + 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`", + ))) + } + } + } +} diff --git a/crates/bevy_reflect/src/serde/de/enums.rs b/crates/bevy_reflect/src/serde/de/enums.rs new file mode 100644 index 0000000000..9350ebce6f --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/enums.rs @@ -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(self, data: A) -> Result + 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(self, deserializer: D) -> Result + 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(self, variant_index: u32) -> Result + 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(self, variant_name: &str) -> Result + 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(self, mut seq: A) -> Result + where + A: SeqAccess<'de>, + { + visit_struct_seq(&mut seq, self.struct_info, self.registration, self.registry) + } + + fn visit_map(self, mut map: V) -> Result + 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(self, mut seq: V) -> Result + where + V: SeqAccess<'de>, + { + visit_tuple(&mut seq, self.tuple_info, self.registration, self.registry) + } +} diff --git a/crates/bevy_reflect/src/serde/de/helpers.rs b/crates/bevy_reflect/src/serde/de/helpers.rs new file mode 100644 index 0000000000..3243a6c011 --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/helpers.rs @@ -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(pub Vec); + +impl FromIterator for ExpectedValues { + fn from_iter>(iter: I) -> Self { + Self(iter.into_iter().collect()) + } +} + +impl Debug for ExpectedValues { + 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(deserializer: D) -> Result + 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(self, value: &str) -> Result + where + E: Error, + { + Ok(Ident(value.to_string())) + } + + fn visit_string(self, value: String) -> Result + where + E: Error, + { + Ok(Ident(value)) + } + } + + deserializer.deserialize_identifier(IdentVisitor) + } +} diff --git a/crates/bevy_reflect/src/serde/de/lists.rs b/crates/bevy_reflect/src/serde/de/lists.rs new file mode 100644 index 0000000000..30e7d9282d --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/lists.rs @@ -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(self, mut seq: V) -> Result + 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) + } +} diff --git a/crates/bevy_reflect/src/serde/de/maps.rs b/crates/bevy_reflect/src/serde/de/maps.rs new file mode 100644 index 0000000000..0b185110d6 --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/maps.rs @@ -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(self, mut map: V) -> Result + 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) + } +} diff --git a/crates/bevy_reflect/src/serde/de/mod.rs b/crates/bevy_reflect/src/serde/de/mod.rs new file mode 100644 index 0000000000..40bf927774 --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/mod.rs @@ -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, + option_value_complex: Option, + tuple_value: (f32, usize), + list_value: Vec, + array_value: [i32; 5], + map_value: HashMap, + set_value: HashSet, + 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::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::<(f32, usize)>(); + registry.register::<[i32; 5]>(); + registry.register::>(); + registry.register::>(); + registry.register::>(); + registry.register::>(); + registry.register::>(); + registry.register_type_data::, 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(®istry); + let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap(); + let dynamic_output = reflect_deserializer + .deserialize(&mut ron_deserializer) + .unwrap(); + + let output = ::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(®istry); + 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::() + .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::(); + let registration = registry.get(TypeId::of::()).unwrap(); + let reflect_deserializer = TypedReflectDeserializer::new(registration, ®istry); + let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap(); + let dynamic_output = reflect_deserializer + .deserialize(&mut ron_deserializer) + .unwrap(); + + let output = + ::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, + complex: Option, + } + + let expected = OptionTest { + none: None, + simple: Some(String::from("Hello world!")), + complex: Some(SomeStruct { foo: 123 }), + }; + + let mut registry = get_registry(); + registry.register::(); + registry.register::>(); + + // === 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(®istry); + let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap(); + let dynamic_output = reflect_deserializer + .deserialize(&mut ron_deserializer) + .unwrap(); + + let output = ::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(®istry); + let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap(); + let dynamic_output = reflect_deserializer + .deserialize(&mut ron_deserializer) + .unwrap(); + + let output = ::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::(); + + // === Unit Variant === // + let input = r#"{ + "bevy_reflect::serde::de::tests::MyEnum": Unit, +}"#; + let reflect_deserializer = ReflectDeserializer::new(®istry); + 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(®istry); + 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(®istry); + 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(®istry); + 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, ®istry); + let serialized1 = ron::ser::to_string(&serializer1).unwrap(); + + let mut deserializer = ron::de::Deserializer::from_str(&serialized1).unwrap(); + let reflect_deserializer = ReflectDeserializer::new(®istry); + let input2 = reflect_deserializer.deserialize(&mut deserializer).unwrap(); + + let serializer2 = ReflectSerializer::new(input2.as_partial_reflect(), ®istry); + 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(®istry); + + let dynamic_output = bincode::DefaultOptions::new() + .with_fixint_encoding() + .deserialize_seed(deserializer, &input) + .unwrap(); + + let output = ::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(®istry); + let dynamic_output = deserializer + .deserialize(&mut rmp_serde::Deserializer::new(&mut reader)) + .unwrap(); + + let output = ::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::>(); + + let input = r#"{"core::ops::RangeInclusive":(start:0.0,end:1.0)}"#; + let mut deserializer = ron::de::Deserializer::from_str(input).unwrap(); + let reflect_deserializer = ReflectDeserializer::new(®istry); + let error = reflect_deserializer + .deserialize(&mut deserializer) + .unwrap_err(); + assert_eq!(error, ron::Error::Message("Type `core::ops::RangeInclusive` did not register the `ReflectDeserialize` type data. For certain types, this may need to be registered manually using `register_type_data`".to_string())); + } +} diff --git a/crates/bevy_reflect/src/serde/de/options.rs b/crates/bevy_reflect/src/serde/de/options.rs new file mode 100644 index 0000000000..103121a4b1 --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/options.rs @@ -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(self) -> Result + where + E: Error, + { + let mut option = DynamicEnum::default(); + option.set_variant("None", ()); + Ok(option) + } + + fn visit_some(self, deserializer: D) -> Result + 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() + ))), + } + } +} diff --git a/crates/bevy_reflect/src/serde/de/registration_utils.rs b/crates/bevy_reflect/src/serde/de/registration_utils.rs new file mode 100644 index 0000000000..8a170d1732 --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/registration_utils.rs @@ -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( + 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) +} diff --git a/crates/bevy_reflect/src/serde/de/registrations.rs b/crates/bevy_reflect/src/serde/de/registrations.rs new file mode 100644 index 0000000000..9ed10628f7 --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/registrations.rs @@ -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(self, deserializer: D) -> Result + 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(self, type_path: &str) -> Result + 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)) + } +} diff --git a/crates/bevy_reflect/src/serde/de/sets.rs b/crates/bevy_reflect/src/serde/de/sets.rs new file mode 100644 index 0000000000..fcb72a8f77 --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/sets.rs @@ -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(self, mut set: V) -> Result + 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) + } +} diff --git a/crates/bevy_reflect/src/serde/de/struct_utils.rs b/crates/bevy_reflect/src/serde/de/struct_utils.rs new file mode 100644 index 0000000000..5035746a60 --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/struct_utils.rs @@ -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(&self, name: &str) -> Result<&NamedField, E>; + fn field_at(&self, index: usize) -> Result<&NamedField, E>; + fn field_len(&self) -> usize; + fn iter_fields(&self) -> Iter<'_, NamedField>; +} + +impl StructLikeInfo for StructInfo { + fn field(&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(&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(&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(&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 +where + T: StructLikeInfo, + V: MapAccess<'de>, +{ + let mut dynamic_struct = DynamicStruct::default(); + while let Some(Ident(key)) = map.next_key::()? { + let field = info.field::(&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::() { + for (skipped_index, skipped_field) in serialization_data.iter_skipped() { + let Ok(field) = info.field_at::(*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 +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::(); + + for index in 0..len { + let name = info.field_at::(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) +} diff --git a/crates/bevy_reflect/src/serde/de/structs.rs b/crates/bevy_reflect/src/serde/de/structs.rs new file mode 100644 index 0000000000..85aa6f15b3 --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/structs.rs @@ -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(self, mut seq: A) -> Result + where + A: SeqAccess<'de>, + { + visit_struct_seq(&mut seq, self.struct_info, self.registration, self.registry) + } + + fn visit_map(self, mut map: V) -> Result + where + V: MapAccess<'de>, + { + visit_struct(&mut map, self.struct_info, self.registration, self.registry) + } +} diff --git a/crates/bevy_reflect/src/serde/de/tuple_structs.rs b/crates/bevy_reflect/src/serde/de/tuple_structs.rs new file mode 100644 index 0000000000..8bbe44a324 --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/tuple_structs.rs @@ -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(self, mut seq: V) -> Result + where + V: SeqAccess<'de>, + { + visit_tuple( + &mut seq, + self.tuple_struct_info, + self.registration, + self.registry, + ) + .map(DynamicTupleStruct::from) + } +} diff --git a/crates/bevy_reflect/src/serde/de/tuple_utils.rs b/crates/bevy_reflect/src/serde/de/tuple_utils.rs new file mode 100644 index 0000000000..542b096bf5 --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/tuple_utils.rs @@ -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(&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(&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(&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(&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 +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::(); + + 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) +} diff --git a/crates/bevy_reflect/src/serde/de/tuples.rs b/crates/bevy_reflect/src/serde/de/tuples.rs new file mode 100644 index 0000000000..de18cbda61 --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/tuples.rs @@ -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(self, mut seq: V) -> Result + where + V: SeqAccess<'de>, + { + visit_tuple(&mut seq, self.tuple_info, self.registration, self.registry) + } +} diff --git a/crates/bevy_reflect/src/serde/ser.rs b/crates/bevy_reflect/src/serde/ser.rs deleted file mode 100644 index 8615171238..0000000000 --- a/crates/bevy_reflect/src/serde/ser.rs +++ /dev/null @@ -1,1012 +0,0 @@ -use crate::{ - Array, Enum, List, Map, PartialReflect, ReflectRef, ReflectSerialize, Set, Struct, Tuple, - TupleStruct, TypeInfo, TypeRegistry, VariantInfo, VariantType, -}; -use serde::ser::{ - Error, SerializeStruct, SerializeStructVariant, SerializeTuple, SerializeTupleStruct, - SerializeTupleVariant, -}; -use serde::{ - ser::{SerializeMap, SerializeSeq}, - Serialize, -}; - -use super::SerializationData; - -pub enum Serializable<'a> { - Owned(Box), - Borrowed(&'a dyn erased_serde::Serialize), -} - -impl<'a> Serializable<'a> { - #[allow(clippy::should_implement_trait)] - pub fn borrow(&self) -> &dyn erased_serde::Serialize { - match self { - Serializable::Borrowed(serialize) => serialize, - Serializable::Owned(serialize) => serialize, - } - } -} - -fn get_serializable<'a, E: Error>( - reflect_value: &'a dyn PartialReflect, - type_registry: &TypeRegistry, -) -> Result, E> { - let Some(reflect_value) = reflect_value.try_as_reflect() else { - return Err(Error::custom(format_args!( - "Type '{}' does not implement `Reflect`", - reflect_value.reflect_type_path() - ))); - }; - let info = reflect_value.get_represented_type_info().ok_or_else(|| { - Error::custom(format_args!( - "Type '{}' does not represent any type", - reflect_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::().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(reflect_value)) -} - -/// 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::(); -/// -/// let input = MyStruct { value: 123 }; -/// -/// let reflect_serializer = ReflectSerializer::new(&input, ®istry); -/// let output = ron::to_string(&reflect_serializer).unwrap(); -/// -/// assert_eq!(output, r#"{"my_crate::MyStruct":(value:123)}"#); -/// ``` -/// -/// [`ReflectDeserializer`]: crate::serde::ReflectDeserializer -/// [type path]: crate::TypePath::type_path -pub struct ReflectSerializer<'a> { - pub value: &'a dyn PartialReflect, - pub 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(&self, serializer: S) -> Result - 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::(); -/// -/// let input = MyStruct { value: 123 }; -/// -/// let reflect_serializer = TypedReflectSerializer::new(&input, ®istry); -/// let output = ron::to_string(&reflect_serializer).unwrap(); -/// -/// assert_eq!(output, r#"(value:123)"#); -/// ``` -/// -/// [`TypedReflectDeserializer`]: crate::serde::TypedReflectDeserializer -/// [type path]: crate::TypePath::type_path -pub struct TypedReflectSerializer<'a> { - pub value: &'a dyn PartialReflect, - pub 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(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - // Handle both Value case and types that have a custom `Serialize` - let serializable = get_serializable::(self.value, self.registry); - if let Ok(serializable) = serializable { - return serializable.borrow().serialize(serializer); - } - - match self.value.reflect_ref() { - ReflectRef::Struct(value) => StructSerializer { - struct_value: value, - registry: self.registry, - } - .serialize(serializer), - ReflectRef::TupleStruct(value) => TupleStructSerializer { - tuple_struct: value, - registry: self.registry, - } - .serialize(serializer), - ReflectRef::Tuple(value) => TupleSerializer { - tuple: value, - registry: self.registry, - } - .serialize(serializer), - ReflectRef::List(value) => ListSerializer { - list: value, - registry: self.registry, - } - .serialize(serializer), - ReflectRef::Array(value) => ArraySerializer { - array: value, - registry: self.registry, - } - .serialize(serializer), - ReflectRef::Map(value) => MapSerializer { - map: value, - registry: self.registry, - } - .serialize(serializer), - ReflectRef::Set(value) => SetSerializer { - set: value, - registry: self.registry, - } - .serialize(serializer), - ReflectRef::Enum(value) => EnumSerializer { - enum_value: value, - registry: self.registry, - } - .serialize(serializer), - ReflectRef::Value(_) => Err(serializable.err().unwrap()), - } - } -} - -pub struct ReflectValueSerializer<'a> { - pub registry: &'a TypeRegistry, - pub value: &'a dyn PartialReflect, -} - -impl<'a> Serialize for ReflectValueSerializer<'a> { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - get_serializable::(self.value, self.registry)? - .borrow() - .serialize(serializer) - } -} - -pub struct StructSerializer<'a> { - pub struct_value: &'a dyn Struct, - pub registry: &'a TypeRegistry, -} - -impl<'a> Serialize for StructSerializer<'a> { - fn serialize(&self, serializer: S) -> Result - 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::()); - 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() - } -} - -pub struct TupleStructSerializer<'a> { - pub tuple_struct: &'a dyn TupleStruct, - pub registry: &'a TypeRegistry, -} - -impl<'a> Serialize for TupleStructSerializer<'a> { - fn serialize(&self, serializer: S) -> Result - 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::()); - 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() - } -} - -pub struct EnumSerializer<'a> { - pub enum_value: &'a dyn Enum, - pub registry: &'a TypeRegistry, -} - -impl<'a> Serialize for EnumSerializer<'a> { - fn serialize(&self, serializer: S) -> Result - 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() - } - } - } -} - -pub struct TupleSerializer<'a> { - pub tuple: &'a dyn Tuple, - pub registry: &'a TypeRegistry, -} - -impl<'a> Serialize for TupleSerializer<'a> { - fn serialize(&self, serializer: S) -> Result - 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() - } -} - -pub struct MapSerializer<'a> { - pub map: &'a dyn Map, - pub registry: &'a TypeRegistry, -} - -impl<'a> Serialize for MapSerializer<'a> { - fn serialize(&self, serializer: S) -> Result - 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() - } -} - -pub struct SetSerializer<'a> { - pub set: &'a dyn Set, - pub registry: &'a TypeRegistry, -} - -impl<'a> Serialize for SetSerializer<'a> { - fn serialize(&self, serializer: S) -> Result - 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() - } -} - -pub struct ListSerializer<'a> { - pub list: &'a dyn List, - pub registry: &'a TypeRegistry, -} - -impl<'a> Serialize for ListSerializer<'a> { - fn serialize(&self, serializer: S) -> Result - 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() - } -} - -pub struct ArraySerializer<'a> { - pub array: &'a dyn Array, - pub registry: &'a TypeRegistry, -} - -impl<'a> Serialize for ArraySerializer<'a> { - fn serialize(&self, serializer: S) -> Result - 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() - } -} - -#[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, - option_value_complex: Option, - tuple_value: (f32, usize), - list_value: Vec, - array_value: [i32; 5], - map_value: HashMap, - set_value: HashSet, - 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::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register_type_data::(); - registry.register::(); - registry.register::>(); - registry.register_type_data::, 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, ®istry); - - 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, - complex: Option, - } - - 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, ®istry); - - // === 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::(); - - let config = PrettyConfig::default().new_line(String::from("\n")); - - // === Unit Variant === // - let value = MyEnum::Unit; - let serializer = ReflectSerializer::new(&value, ®istry); - 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, ®istry); - 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, ®istry); - 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, ®istry); - 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, ®istry); - let bytes = bincode::serialize(&serializer).unwrap(); - - let expected: Vec = 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, ®istry); - let bytes: Vec = rmp_serde::to_vec(&serializer).unwrap(); - - let expected: Vec = 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, - none: Option, - } - - 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, ®istry); - - 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::::new(0.0, 1.0); - let registry = TypeRegistry::new(); - - let serializer = ReflectSerializer::new(&value, ®istry); - let error = ron::ser::to_string(&serializer).unwrap_err(); - assert_eq!( - error, - ron::Error::Message( - "Type `core::ops::RangeInclusive` is not registered in the type registry" - .to_string() - ) - ); - } - - #[test] - fn should_return_error_if_missing_type_data() { - let value = RangeInclusive::::new(0.0, 1.0); - let mut registry = TypeRegistry::new(); - registry.register::>(); - - let serializer = ReflectSerializer::new(&value, ®istry); - let error = ron::ser::to_string(&serializer).unwrap_err(); - assert_eq!( - error, - ron::Error::Message( - "Type `core::ops::RangeInclusive` did not register the `ReflectSerialize` type data. For certain types, this may need to be registered manually using `register_type_data`".to_string() - ) - ); - } -} diff --git a/crates/bevy_reflect/src/serde/ser/arrays.rs b/crates/bevy_reflect/src/serde/ser/arrays.rs new file mode 100644 index 0000000000..eb84919dfd --- /dev/null +++ b/crates/bevy_reflect/src/serde/ser/arrays.rs @@ -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(&self, serializer: S) -> Result + 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() + } +} diff --git a/crates/bevy_reflect/src/serde/ser/enums.rs b/crates/bevy_reflect/src/serde/ser/enums.rs new file mode 100644 index 0000000000..da151cc894 --- /dev/null +++ b/crates/bevy_reflect/src/serde/ser/enums.rs @@ -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(&self, serializer: S) -> Result + 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() + } + } + } +} diff --git a/crates/bevy_reflect/src/serde/ser/lists.rs b/crates/bevy_reflect/src/serde/ser/lists.rs new file mode 100644 index 0000000000..6e6b98958b --- /dev/null +++ b/crates/bevy_reflect/src/serde/ser/lists.rs @@ -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(&self, serializer: S) -> Result + 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() + } +} diff --git a/crates/bevy_reflect/src/serde/ser/maps.rs b/crates/bevy_reflect/src/serde/ser/maps.rs new file mode 100644 index 0000000000..589cfae3d1 --- /dev/null +++ b/crates/bevy_reflect/src/serde/ser/maps.rs @@ -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(&self, serializer: S) -> Result + 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() + } +} diff --git a/crates/bevy_reflect/src/serde/ser/mod.rs b/crates/bevy_reflect/src/serde/ser/mod.rs new file mode 100644 index 0000000000..85876fabf2 --- /dev/null +++ b/crates/bevy_reflect/src/serde/ser/mod.rs @@ -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, + option_value_complex: Option, + tuple_value: (f32, usize), + list_value: Vec, + array_value: [i32; 5], + map_value: HashMap, + set_value: HashSet, + 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::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register_type_data::(); + registry.register::(); + registry.register::>(); + registry.register_type_data::, 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, ®istry); + + 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, + complex: Option, + } + + 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, ®istry); + + // === 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::(); + + let config = PrettyConfig::default().new_line(String::from("\n")); + + // === Unit Variant === // + let value = MyEnum::Unit; + let serializer = ReflectSerializer::new(&value, ®istry); + 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, ®istry); + 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, ®istry); + 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, ®istry); + 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, ®istry); + let bytes = bincode::serialize(&serializer).unwrap(); + + let expected: Vec = 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, ®istry); + let bytes: Vec = rmp_serde::to_vec(&serializer).unwrap(); + + let expected: Vec = 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, + none: Option, + } + + 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, ®istry); + + 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::::new(0.0, 1.0); + let registry = TypeRegistry::new(); + + let serializer = ReflectSerializer::new(&value, ®istry); + let error = ron::ser::to_string(&serializer).unwrap_err(); + assert_eq!( + error, + ron::Error::Message( + "Type `core::ops::RangeInclusive` is not registered in the type registry" + .to_string() + ) + ); + } + + #[test] + fn should_return_error_if_missing_type_data() { + let value = RangeInclusive::::new(0.0, 1.0); + let mut registry = TypeRegistry::new(); + registry.register::>(); + + let serializer = ReflectSerializer::new(&value, ®istry); + let error = ron::ser::to_string(&serializer).unwrap_err(); + assert_eq!( + error, + ron::Error::Message( + "Type `core::ops::RangeInclusive` did not register the `ReflectSerialize` type data. For certain types, this may need to be registered manually using `register_type_data`".to_string() + ) + ); + } +} diff --git a/crates/bevy_reflect/src/serde/ser/serializable.rs b/crates/bevy_reflect/src/serde/ser/serializable.rs new file mode 100644 index 0000000000..9c285816f2 --- /dev/null +++ b/crates/bevy_reflect/src/serde/ser/serializable.rs @@ -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), + 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( + value: &'a dyn PartialReflect, + type_registry: &TypeRegistry, + ) -> Result, 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::().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, + } + } +} diff --git a/crates/bevy_reflect/src/serde/ser/serializer.rs b/crates/bevy_reflect/src/serde/ser/serializer.rs new file mode 100644 index 0000000000..eb3afe96f8 --- /dev/null +++ b/crates/bevy_reflect/src/serde/ser/serializer.rs @@ -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::(); +/// +/// let input = MyStruct { value: 123 }; +/// +/// let reflect_serializer = ReflectSerializer::new(&input, ®istry); +/// let output = ron::to_string(&reflect_serializer).unwrap(); +/// +/// assert_eq!(output, r#"{"my_crate::MyStruct":(value:123)}"#); +/// ``` +/// +/// [`ReflectDeserializer`]: crate::serde::ReflectDeserializer +/// [type path]: crate::TypePath::type_path +pub struct ReflectSerializer<'a> { + 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(&self, serializer: S) -> Result + 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::(); +/// +/// let input = MyStruct { value: 123 }; +/// +/// let reflect_serializer = TypedReflectSerializer::new(&input, ®istry); +/// let output = ron::to_string(&reflect_serializer).unwrap(); +/// +/// assert_eq!(output, r#"(value:123)"#); +/// ``` +/// +/// [`TypedReflectDeserializer`]: crate::serde::TypedReflectDeserializer +/// [type path]: crate::TypePath::type_path +pub struct TypedReflectSerializer<'a> { + 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(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + // Handle both Value case and types that have a custom `Serialize` + let serializable = + Serializable::try_from_reflect_value::(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()), + } + } +} diff --git a/crates/bevy_reflect/src/serde/ser/sets.rs b/crates/bevy_reflect/src/serde/ser/sets.rs new file mode 100644 index 0000000000..9a5abab572 --- /dev/null +++ b/crates/bevy_reflect/src/serde/ser/sets.rs @@ -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(&self, serializer: S) -> Result + 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() + } +} diff --git a/crates/bevy_reflect/src/serde/ser/structs.rs b/crates/bevy_reflect/src/serde/ser/structs.rs new file mode 100644 index 0000000000..2c31280f05 --- /dev/null +++ b/crates/bevy_reflect/src/serde/ser/structs.rs @@ -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(&self, serializer: S) -> Result + 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::()); + 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() + } +} diff --git a/crates/bevy_reflect/src/serde/ser/tuple_structs.rs b/crates/bevy_reflect/src/serde/ser/tuple_structs.rs new file mode 100644 index 0000000000..e60c9ad66c --- /dev/null +++ b/crates/bevy_reflect/src/serde/ser/tuple_structs.rs @@ -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(&self, serializer: S) -> Result + 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::()); + 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() + } +} diff --git a/crates/bevy_reflect/src/serde/ser/tuples.rs b/crates/bevy_reflect/src/serde/ser/tuples.rs new file mode 100644 index 0000000000..c3b90d5f56 --- /dev/null +++ b/crates/bevy_reflect/src/serde/ser/tuples.rs @@ -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(&self, serializer: S) -> Result + 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() + } +}