diff --git a/assets/scenes/load_scene_example.scn.ron b/assets/scenes/load_scene_example.scn.ron index 338084e9671b6..8400e28f6e2aa 100644 --- a/assets/scenes/load_scene_example.scn.ron +++ b/assets/scenes/load_scene_example.scn.ron @@ -3,42 +3,29 @@ entity: 0, components: [ { - "type": "bevy_transform::components::transform::Transform", - "struct": { + "bevy_transform::components::transform::Transform": { "translation": { - "type": "glam::f32::vec3::Vec3", - "value": (0.0, 0.0, 0.0), - }, - "rotation": { - "type": "glam::f32::sse2::quat::Quat", - "value": (0.0, 0.0, 0.0, 1.0), + "x": 0.0, + "y": 0.0, + "z": 0.0 }, + "rotation": (0.0, 0.0, 0.0, 1.0), "scale": { - "type": "glam::f32::vec3::Vec3", - "value": (1.0, 1.0, 1.0), + "x": 1.0, + "y": 1.0, + "z": 1.0 }, }, }, { - "type": "scene::ComponentB", - "struct": { - "value": { - "type": "alloc::string::String", - "value": "hello", - }, + "scene::ComponentB": { + "value": "hello", }, }, { - "type": "scene::ComponentA", - "struct": { - "x": { - "type": "f32", - "value": 1.0, - }, - "y": { - "type": "f32", - "value": 2.0, - }, + "scene::ComponentA": { + "x": 1.0, + "y": 2.0, }, }, ], @@ -47,16 +34,9 @@ entity: 1, components: [ { - "type": "scene::ComponentA", - "struct": { - "x": { - "type": "f32", - "value": 3.0, - }, - "y": { - "type": "f32", - "value": 4.0, - }, + "scene::ComponentA": { + "x": 3.0, + "y": 4.0, }, }, ], diff --git a/crates/bevy_reflect/src/impls/glam.rs b/crates/bevy_reflect/src/impls/glam.rs index c84fcbffaaf27..9dfcc8293ce23 100644 --- a/crates/bevy_reflect/src/impls/glam.rs +++ b/crates/bevy_reflect/src/impls/glam.rs @@ -6,14 +6,14 @@ use bevy_reflect_derive::{impl_from_reflect_value, impl_reflect_struct, impl_ref use glam::*; impl_reflect_struct!( - #[reflect(Debug, PartialEq, Serialize, Deserialize, Default)] + #[reflect(Debug, PartialEq, Default)] struct IVec2 { x: i32, y: i32, } ); impl_reflect_struct!( - #[reflect(Debug, PartialEq, Serialize, Deserialize, Default)] + #[reflect(Debug, PartialEq, Default)] struct IVec3 { x: i32, y: i32, @@ -21,7 +21,7 @@ impl_reflect_struct!( } ); impl_reflect_struct!( - #[reflect(Debug, PartialEq, Serialize, Deserialize, Default)] + #[reflect(Debug, PartialEq, Default)] struct IVec4 { x: i32, y: i32, @@ -31,14 +31,14 @@ impl_reflect_struct!( ); impl_reflect_struct!( - #[reflect(Debug, PartialEq, Serialize, Deserialize, Default)] + #[reflect(Debug, PartialEq, Default)] struct UVec2 { x: u32, y: u32, } ); impl_reflect_struct!( - #[reflect(Debug, PartialEq, Serialize, Deserialize, Default)] + #[reflect(Debug, PartialEq, Default)] struct UVec3 { x: u32, y: u32, @@ -46,7 +46,7 @@ impl_reflect_struct!( } ); impl_reflect_struct!( - #[reflect(Debug, PartialEq, Serialize, Deserialize, Default)] + #[reflect(Debug, PartialEq, Default)] struct UVec4 { x: u32, y: u32, @@ -56,14 +56,14 @@ impl_reflect_struct!( ); impl_reflect_struct!( - #[reflect(Debug, PartialEq, Serialize, Deserialize, Default)] + #[reflect(Debug, PartialEq, Default)] struct Vec2 { x: f32, y: f32, } ); impl_reflect_struct!( - #[reflect(Debug, PartialEq, Serialize, Deserialize, Default)] + #[reflect(Debug, PartialEq, Default)] struct Vec3 { x: f32, y: f32, @@ -71,7 +71,7 @@ impl_reflect_struct!( } ); impl_reflect_struct!( - #[reflect(Debug, PartialEq, Serialize, Deserialize, Default)] + #[reflect(Debug, PartialEq, Default)] struct Vec3A { x: f32, y: f32, @@ -79,7 +79,7 @@ impl_reflect_struct!( } ); impl_reflect_struct!( - #[reflect(Debug, PartialEq, Serialize, Deserialize, Default)] + #[reflect(Debug, PartialEq, Default)] struct Vec4 { x: f32, y: f32, @@ -114,14 +114,14 @@ impl_reflect_struct!( ); impl_reflect_struct!( - #[reflect(Debug, PartialEq, Serialize, Deserialize, Default)] + #[reflect(Debug, PartialEq, Default)] struct DVec2 { x: f64, y: f64, } ); impl_reflect_struct!( - #[reflect(Debug, PartialEq, Serialize, Deserialize, Default)] + #[reflect(Debug, PartialEq, Default)] struct DVec3 { x: f64, y: f64, @@ -129,7 +129,7 @@ impl_reflect_struct!( } ); impl_reflect_struct!( - #[reflect(Debug, PartialEq, Serialize, Deserialize, Default)] + #[reflect(Debug, PartialEq, Default)] struct DVec4 { x: f64, y: f64, diff --git a/crates/bevy_reflect/src/lib.rs b/crates/bevy_reflect/src/lib.rs index 5f35d27e4e5a3..66c486e5e8ed3 100644 --- a/crates/bevy_reflect/src/lib.rs +++ b/crates/bevy_reflect/src/lib.rs @@ -93,7 +93,7 @@ pub mod __macro_exports { mod tests { #[cfg(feature = "glam")] use ::glam::{vec3, Vec3}; - use ::serde::de::DeserializeSeed; + use ::serde::{de::DeserializeSeed, Deserialize, Serialize}; use bevy_utils::HashMap; use ron::{ ser::{to_string_pretty, PrettyConfig}, @@ -104,7 +104,7 @@ mod tests { use super::prelude::*; use super::*; use crate as bevy_reflect; - use crate::serde::{ReflectDeserializer, ReflectSerializer}; + use crate::serde::{ReflectSerializer, UntypedReflectDeserializer}; #[test] fn reflect_struct() { @@ -451,7 +451,8 @@ mod tests { h: [u32; 2], } - #[derive(Reflect)] + #[derive(Reflect, Serialize, Deserialize)] + #[reflect(Serialize, Deserialize)] struct Bar { x: u32, } @@ -472,18 +473,23 @@ mod tests { 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::<(i32, Vec, Bar)>(); + registry.register::<[u32; 2]>(); let serializer = ReflectSerializer::new(&foo, ®istry); let serialized = to_string_pretty(&serializer, PrettyConfig::default()).unwrap(); let mut deserializer = Deserializer::from_str(&serialized).unwrap(); - let reflect_deserializer = ReflectDeserializer::new(®istry); + let reflect_deserializer = UntypedReflectDeserializer::new(®istry); let value = reflect_deserializer.deserialize(&mut deserializer).unwrap(); let dynamic_struct = value.take::().unwrap(); @@ -952,23 +958,39 @@ bevy_reflect::tests::should_reflect_debug::Test { let ser = ReflectSerializer::new(&v, ®istry); - let result = ron::to_string(&ser).expect("Failed to serialize to string"); + let config = PrettyConfig::default() + .new_line(String::from("\n")) + .decimal_floats(true) + .indentor(String::from(" ")); + let output = to_string_pretty(&ser, config).unwrap(); + let expected = r#" +{ + "glam::f32::vec3::Vec3": { + "x": 12.0, + "y": 3.0, + "z": -6.9, + }, +}"#; - assert_eq!( - result, - r#"{"type":"glam::f32::vec3::Vec3","struct":{"x":{"type":"f32","value":12.0},"y":{"type":"f32","value":3.0},"z":{"type":"f32","value":-6.9}}}"# - ); + assert_eq!(expected, format!("\n{}", output)); } #[test] fn vec3_deserialization() { - let data = r#"{"type":"glam::vec3::Vec3","struct":{"x":{"type":"f32","value":12},"y":{"type":"f32","value":3},"z":{"type":"f32","value":-6.9}}}"#; + let data = r#" +{ + "glam::f32::vec3::Vec3": { + "x": 12.0, + "y": 3.0, + "z": -6.9, + }, +}"#; let mut registry = TypeRegistry::default(); registry.add_registration(Vec3::get_type_registration()); registry.add_registration(f32::get_type_registration()); - let de = ReflectDeserializer::new(®istry); + let de = UntypedReflectDeserializer::new(®istry); let mut deserializer = ron::de::Deserializer::from_str(data).expect("Failed to acquire deserializer"); diff --git a/crates/bevy_reflect/src/serde/de.rs b/crates/bevy_reflect/src/serde/de.rs index ad24185de15f3..f95dc3e126e17 100644 --- a/crates/bevy_reflect/src/serde/de.rs +++ b/crates/bevy_reflect/src/serde/de.rs @@ -1,9 +1,13 @@ use crate::{ - serde::type_fields, DynamicArray, DynamicEnum, DynamicList, DynamicMap, DynamicStruct, - DynamicTuple, DynamicTupleStruct, Map, Reflect, ReflectDeserialize, TypeRegistry, + ArrayInfo, DynamicArray, DynamicEnum, DynamicList, DynamicMap, DynamicStruct, DynamicTuple, + DynamicTupleStruct, EnumInfo, ListInfo, Map, MapInfo, NamedField, Reflect, ReflectDeserialize, + StructInfo, StructVariantInfo, Tuple, TupleInfo, TupleStruct, TupleStructInfo, + TupleVariantInfo, TypeInfo, TypeRegistry, UnnamedField, VariantInfo, }; use erased_serde::Deserializer; use serde::de::{self, DeserializeSeed, Error, MapAccess, SeqAccess, Visitor}; +use std::any::TypeId; +use std::fmt::Formatter; pub trait DeserializeValue { fn deserialize( @@ -12,321 +16,381 @@ pub trait DeserializeValue { ) -> Result, erased_serde::Error>; } -pub struct ReflectDeserializer<'a> { - registry: &'a TypeRegistry, +trait StructLikeInfo { + fn get_name(&self) -> &str; + fn get_field(&self, name: &str) -> Option<&NamedField>; } -impl<'a> ReflectDeserializer<'a> { - pub fn new(registry: &'a TypeRegistry) -> Self { - ReflectDeserializer { registry } - } +trait TupleLikeInfo { + fn get_name(&self) -> &str; + fn get_field(&self, index: usize) -> Option<&UnnamedField>; + fn get_field_len(&self) -> usize; } -impl<'a, 'de> DeserializeSeed<'de> for ReflectDeserializer<'a> { - type Value = Box; - - fn deserialize(self, deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - deserializer.deserialize_any(ReflectVisitor { - registry: self.registry, - }) +impl StructLikeInfo for StructInfo { + fn get_name(&self) -> &str { + self.type_name() } -} -struct ReflectVisitor<'a> { - registry: &'a TypeRegistry, + fn get_field(&self, name: &str) -> Option<&NamedField> { + self.field(name) + } } -impl<'a, 'de> Visitor<'de> for ReflectVisitor<'a> { - type Value = Box; - - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - formatter.write_str("reflect value") +impl StructLikeInfo for StructVariantInfo { + fn get_name(&self) -> &str { + self.name() } - fn visit_u8(self, v: u8) -> Result - where - E: de::Error, - { - Ok(Box::new(v)) + fn get_field(&self, name: &str) -> Option<&NamedField> { + self.field(name) } +} - fn visit_bool(self, v: bool) -> Result - where - E: de::Error, - { - Ok(Box::new(v)) +impl TupleLikeInfo for TupleInfo { + fn get_name(&self) -> &str { + self.type_name() } - fn visit_u16(self, v: u16) -> Result - where - E: de::Error, - { - Ok(Box::new(v)) + fn get_field(&self, index: usize) -> Option<&UnnamedField> { + self.field_at(index) } - fn visit_u32(self, v: u32) -> Result - where - E: de::Error, - { - Ok(Box::new(v)) + fn get_field_len(&self) -> usize { + self.field_len() } +} - fn visit_u64(self, v: u64) -> Result - where - E: de::Error, - { - Ok(Box::new(v)) +impl TupleLikeInfo for TupleVariantInfo { + fn get_name(&self) -> &str { + self.name() } - fn visit_i8(self, v: i8) -> Result - where - E: de::Error, - { - Ok(Box::new(v)) + fn get_field(&self, index: usize) -> Option<&UnnamedField> { + self.field_at(index) } - fn visit_i16(self, v: i16) -> Result - where - E: de::Error, - { - Ok(Box::new(v)) + fn get_field_len(&self) -> usize { + self.field_len() } +} - fn visit_i32(self, v: i32) -> Result - where - E: de::Error, - { - Ok(Box::new(v)) - } +/// A general purpose deserializer for reflected types. +/// +/// This will return a [`Box`] containing the deserialized data. +/// For non-value types, this `Box` will contain the dynamic equivalent. For example, a +/// deserialized struct will return a [`DynamicStruct`] and a `Vec` will return a +/// [`DynamicList`]. For value types, this `Box` will contain the actual value. +/// For example, an `f32` will contain the actual `f32` type. +/// +/// This means that converting to any concrete instance will require the use of +/// [`FromReflect`], or downcasting for value types. +/// +/// Because the type isn't known ahead of time, the serialized data must take the form of +/// a map containing the following entries (in order): +/// 1. `type`: The _full_ [type name] +/// 2. `value`: The serialized value of the reflected type +/// +/// If the type is already known and the [`TypeInfo`] for it can be retrieved, +/// [`TypedReflectDeserializer`] may be used instead to avoid requiring these entries. +/// +/// [`Box`]: crate::Reflect +/// [`DynamicStruct`]: crate::DynamicStruct +/// [`DynamicList`]: crate::DynamicList +/// [`FromReflect`]: crate::FromReflect +/// [type name]: std::any::type_name +pub struct UntypedReflectDeserializer<'a> { + registry: &'a TypeRegistry, +} - fn visit_i64(self, v: i64) -> Result - where - E: de::Error, - { - Ok(Box::new(v)) +impl<'a> UntypedReflectDeserializer<'a> { + pub fn new(registry: &'a TypeRegistry) -> Self { + Self { registry } } +} - fn visit_f32(self, v: f32) -> Result - where - E: de::Error, - { - Ok(Box::new(v)) - } +impl<'a, 'de> DeserializeSeed<'de> for UntypedReflectDeserializer<'a> { + type Value = Box; - fn visit_f64(self, v: f64) -> Result + fn deserialize(self, deserializer: D) -> Result where - E: de::Error, + D: serde::Deserializer<'de>, { - Ok(Box::new(v)) + deserializer.deserialize_any(UntypedReflectDeserializerVisitor { + registry: self.registry, + }) } +} - fn visit_string(self, v: String) -> Result - where - E: de::Error, - { - Ok(Box::new(v)) - } +struct UntypedReflectDeserializerVisitor<'a> { + registry: &'a TypeRegistry, +} - fn visit_str(self, v: &str) -> Result - where - E: de::Error, - { - Ok(Box::new(v.to_string())) +impl<'a, 'de> Visitor<'de> for UntypedReflectDeserializerVisitor<'a> { + type Value = Box; + + fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result { + formatter.write_str("map containing `type` and `value` entries for the reflected value") } - fn visit_map(self, mut map: V) -> Result + fn visit_map(self, mut map: A) -> Result where - V: MapAccess<'de>, + A: MapAccess<'de>, { - let mut type_name: Option = None; - while let Some(key) = map.next_key::()? { - match key.as_str() { - type_fields::TYPE => { - type_name = Some(map.next_value()?); - } - type_fields::MAP => { - let _type_name = type_name - .take() - .ok_or_else(|| de::Error::missing_field(type_fields::TYPE))?; - let map = map.next_value_seed(MapDeserializer { - registry: self.registry, - })?; - return Ok(Box::new(map)); - } - type_fields::STRUCT => { - let type_name = type_name - .take() - .ok_or_else(|| de::Error::missing_field(type_fields::TYPE))?; - let mut dynamic_struct = map.next_value_seed(StructDeserializer { - registry: self.registry, - })?; - dynamic_struct.set_name(type_name); - return Ok(Box::new(dynamic_struct)); - } - type_fields::TUPLE_STRUCT => { - let type_name = type_name - .take() - .ok_or_else(|| de::Error::missing_field(type_fields::TYPE))?; - let mut tuple_struct = map.next_value_seed(TupleStructDeserializer { - registry: self.registry, - })?; - tuple_struct.set_name(type_name); - return Ok(Box::new(tuple_struct)); - } - type_fields::TUPLE => { - let _type_name = type_name - .take() - .ok_or_else(|| de::Error::missing_field(type_fields::TYPE))?; - let tuple = map.next_value_seed(TupleDeserializer { - registry: self.registry, - })?; - return Ok(Box::new(tuple)); - } - type_fields::LIST => { - let _type_name = type_name - .take() - .ok_or_else(|| de::Error::missing_field(type_fields::TYPE))?; - let list = map.next_value_seed(ListDeserializer { - registry: self.registry, - })?; - return Ok(Box::new(list)); - } - type_fields::ARRAY => { - let _type_name = type_name - .take() - .ok_or_else(|| de::Error::missing_field(type_fields::TYPE))?; - let array = map.next_value_seed(ArrayDeserializer { - registry: self.registry, - })?; - return Ok(Box::new(array)); - } - type_fields::ENUM => { - let type_name = type_name - .take() - .ok_or_else(|| de::Error::missing_field(type_fields::TYPE))?; - let mut dynamic_enum = map.next_value_seed(EnumDeserializer { - registry: self.registry, - })?; - dynamic_enum.set_name(type_name); - return Ok(Box::new(dynamic_enum)); - } - type_fields::VALUE => { - let type_name = type_name - .take() - .ok_or_else(|| de::Error::missing_field(type_fields::TYPE))?; - let registration = - self.registry.get_with_name(&type_name).ok_or_else(|| { - de::Error::custom(format_args!( - "No registration found for {}", - type_name - )) - })?; - let deserialize_reflect = - registration.data::().ok_or_else(|| { - de::Error::custom(format_args!( - "The TypeRegistration for {} doesn't have DeserializeReflect", - type_name - )) - })?; - let value = map.next_value_seed(DeserializeReflectDeserializer { - reflect_deserialize: deserialize_reflect, - })?; - return Ok(value); - } - _ => return Err(de::Error::unknown_field(key.as_str(), &[])), - } - } - - Err(de::Error::custom("Maps in this location must have the \'type\' field and one of the following fields: \'map\', \'seq\', \'value\'")) - } + let type_name = map + .next_key::()? + .ok_or_else(|| Error::invalid_length(0, &"at least one entry"))?; + + let registration = self.registry.get_with_name(&type_name).ok_or_else(|| { + Error::custom(format_args!("No registration found for {}", type_name)) + })?; + let type_info = registration.type_info(); + let value = map.next_value_seed(TypedReflectDeserializer { + type_info, + registry: self.registry, + })?; + Ok(value) + } +} + +/// A deserializer for reflected types whose [`TypeInfo`] is known. +/// +/// This will return a [`Box`] containing the deserialized data. +/// For non-value types, this `Box` will contain the dynamic equivalent. For example, a +/// deserialized struct will return a [`DynamicStruct`] and a `Vec` will return a +/// [`DynamicList`]. For value types, this `Box` will contain the actual value. +/// For example, an `f32` will contain the actual `f32` type. +/// +/// This means that converting to any concrete instance will require the use of +/// [`FromReflect`], or downcasting for value types. +/// +/// If the type is not known ahead of time, use [`UntypedReflectDeserializer`] instead. +/// +/// [`TypeInfo`]: crate::TypeInfo +/// [`Box`]: crate::Reflect +/// [`DynamicStruct`]: crate::DynamicStruct +/// [`DynamicList`]: crate::DynamicList +/// [`FromReflect`]: crate::FromReflect +pub struct TypedReflectDeserializer<'a> { + type_info: &'a TypeInfo, + registry: &'a TypeRegistry, } -struct DeserializeReflectDeserializer<'a> { - reflect_deserialize: &'a ReflectDeserialize, +impl<'a> TypedReflectDeserializer<'a> { + pub fn new(type_info: &'a TypeInfo, registry: &'a TypeRegistry) -> Self { + Self { + type_info, + registry, + } + } } -impl<'a, 'de> DeserializeSeed<'de> for DeserializeReflectDeserializer<'a> { +impl<'a, 'de> DeserializeSeed<'de> for TypedReflectDeserializer<'a> { type Value = Box; fn deserialize(self, deserializer: D) -> Result where D: serde::Deserializer<'de>, { - self.reflect_deserialize.deserialize(deserializer) + // Handle both Value case and types that have a custom `ReflectDeserialize` + let type_id = self.type_info.type_id(); + let type_name = self.type_info.type_name(); + let registration = self.registry.get(type_id).ok_or_else(|| { + de::Error::custom(format_args!("no registration found for {}", type_name)) + })?; + + if let Some(deserialize_reflect) = registration.data::() { + let value = deserialize_reflect.deserialize(deserializer)?; + return Ok(value); + } + + match self.type_info { + TypeInfo::Struct(struct_info) => { + let mut dynamic_struct = deserializer.deserialize_map(StructVisitor { + struct_info, + registry: self.registry, + })?; + dynamic_struct.set_name(struct_info.type_name().to_string()); + Ok(Box::new(dynamic_struct)) + } + TypeInfo::TupleStruct(tuple_struct_info) => { + let mut dynamic_tuple_struct = deserializer.deserialize_tuple( + tuple_struct_info.field_len(), + TupleStructVisitor { + tuple_struct_info, + registry: self.registry, + }, + )?; + dynamic_tuple_struct.set_name(tuple_struct_info.type_name().to_string()); + 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_name(list_info.type_name().to_string()); + 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_name(array_info.type_name().to_string()); + 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_name(map_info.type_name().to_string()); + Ok(Box::new(dynamic_map)) + } + TypeInfo::Tuple(tuple_info) => { + let mut dynamic_tuple = deserializer.deserialize_tuple( + tuple_info.field_len(), + TupleVisitor { + tuple_info, + registry: self.registry, + }, + )?; + dynamic_tuple.set_name(tuple_info.type_name().to_string()); + Ok(Box::new(dynamic_tuple)) + } + TypeInfo::Enum(enum_info) => { + let mut dynamic_enum = deserializer.deserialize_map(EnumVisitor { + enum_info, + registry: self.registry, + })?; + dynamic_enum.set_name(enum_info.type_name().to_string()); + Ok(Box::new(dynamic_enum)) + } + TypeInfo::Value(_) => { + // This case should already be handled + Err(de::Error::custom(format_args!( + "the TypeRegistration for {} doesn't have ReflectDeserialize", + type_name + ))) + } + TypeInfo::Dynamic(_) => { + // We could potentially allow this but we'd have no idea what the actual types of the + // fields are and would rely on the deserializer to determine them (e.g. `i32` vs `i64`) + Err(de::Error::custom(format_args!( + "cannot deserialize arbitrary dynamic type {}", + type_name + ))) + } + } } } -struct ListDeserializer<'a> { +struct StructVisitor<'a> { + struct_info: &'a StructInfo, registry: &'a TypeRegistry, } -impl<'a, 'de> DeserializeSeed<'de> for ListDeserializer<'a> { - type Value = DynamicList; +impl<'a, 'de> Visitor<'de> for StructVisitor<'a> { + type Value = DynamicStruct; - fn deserialize(self, deserializer: D) -> Result + fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result { + formatter.write_str("reflected struct value") + } + + fn visit_map(self, mut map: V) -> Result where - D: serde::Deserializer<'de>, + V: MapAccess<'de>, { - deserializer.deserialize_seq(ListVisitor { - registry: self.registry, - }) + visit_struct(&mut map, self.struct_info, self.registry) } } -struct ListVisitor<'a> { +struct TupleStructVisitor<'a> { + tuple_struct_info: &'a TupleStructInfo, registry: &'a TypeRegistry, } -impl<'a, 'de> Visitor<'de> for ListVisitor<'a> { - type Value = DynamicList; +impl<'a, 'de> Visitor<'de> for TupleStructVisitor<'a> { + type Value = DynamicTupleStruct; - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - formatter.write_str("list value") + fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result { + formatter.write_str("reflected tuple struct value") } fn visit_seq(self, mut seq: V) -> Result where V: SeqAccess<'de>, { - let mut list = DynamicList::default(); - while let Some(value) = seq.next_element_seed(ReflectDeserializer { + let mut index = 0usize; + let mut tuple_struct = DynamicTupleStruct::default(); + + let get_field_info = |index: usize| -> Result<&'a TypeInfo, V::Error> { + let field = self.tuple_struct_info.field_at(index).ok_or_else(|| { + de::Error::custom(format_args!( + "no field at index {} on tuple {}", + index, + self.tuple_struct_info.type_name(), + )) + })?; + get_type_info(field.type_id(), field.type_name(), self.registry) + }; + + while let Some(value) = seq.next_element_seed(TypedReflectDeserializer { + type_info: get_field_info(index)?, registry: self.registry, })? { - list.push_box(value); + tuple_struct.insert_boxed(value); + index += 1; + if index >= self.tuple_struct_info.field_len() { + break; + } } - Ok(list) + + if tuple_struct.field_len() != self.tuple_struct_info.field_len() { + return Err(Error::invalid_length( + tuple_struct.field_len(), + &self.tuple_struct_info.field_len().to_string().as_str(), + )); + } + + Ok(tuple_struct) } } -struct ArrayDeserializer<'a> { +struct TupleVisitor<'a> { + tuple_info: &'a TupleInfo, registry: &'a TypeRegistry, } -impl<'a, 'de> DeserializeSeed<'de> for ArrayDeserializer<'a> { - type Value = DynamicArray; +impl<'a, 'de> Visitor<'de> for TupleVisitor<'a> { + type Value = DynamicTuple; - fn deserialize(self, deserializer: D) -> Result + fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result { + formatter.write_str("reflected tuple value") + } + + fn visit_seq(self, mut seq: V) -> Result where - D: serde::Deserializer<'de>, + V: SeqAccess<'de>, { - deserializer.deserialize_seq(ArrayVisitor { - registry: self.registry, - }) + visit_tuple(&mut seq, self.tuple_info, self.registry) } } struct ArrayVisitor<'a> { + array_info: &'a ArrayInfo, registry: &'a TypeRegistry, } impl<'a, 'de> Visitor<'de> for ArrayVisitor<'a> { type Value = DynamicArray; - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - formatter.write_str("array value") + fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result { + formatter.write_str("reflected array value") } fn visit_seq(self, mut seq: V) -> Result @@ -334,42 +398,71 @@ impl<'a, 'de> Visitor<'de> for ArrayVisitor<'a> { V: SeqAccess<'de>, { let mut vec = Vec::with_capacity(seq.size_hint().unwrap_or_default()); - while let Some(value) = seq.next_element_seed(ReflectDeserializer { + let type_info = get_type_info( + self.array_info.item_type_id(), + self.array_info.item_type_name(), + self.registry, + )?; + while let Some(value) = seq.next_element_seed(TypedReflectDeserializer { + type_info, registry: self.registry, })? { vec.push(value); } - Ok(DynamicArray::new(Box::from(vec))) + 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 MapDeserializer<'a> { +struct ListVisitor<'a> { + list_info: &'a ListInfo, registry: &'a TypeRegistry, } -impl<'a, 'de> DeserializeSeed<'de> for MapDeserializer<'a> { - type Value = DynamicMap; +impl<'a, 'de> Visitor<'de> for ListVisitor<'a> { + type Value = DynamicList; - fn deserialize(self, deserializer: D) -> Result + fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result { + formatter.write_str("reflected list value") + } + + fn visit_seq(self, mut seq: V) -> Result where - D: serde::Deserializer<'de>, + V: SeqAccess<'de>, { - deserializer.deserialize_map(MapVisitor { + let mut list = DynamicList::default(); + let type_info = get_type_info( + self.list_info.item_type_id(), + self.list_info.item_type_name(), + self.registry, + )?; + while let Some(value) = seq.next_element_seed(TypedReflectDeserializer { + type_info, registry: self.registry, - }) + })? { + list.push_box(value); + } + Ok(list) } } struct MapVisitor<'a> { + map_info: &'a MapInfo, registry: &'a TypeRegistry, } impl<'a, 'de> Visitor<'de> for MapVisitor<'a> { type Value = DynamicMap; - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - formatter.write_str("map value") + fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result { + formatter.write_str("reflected map value") } fn visit_map(self, mut map: V) -> Result @@ -377,10 +470,22 @@ impl<'a, 'de> Visitor<'de> for MapVisitor<'a> { V: MapAccess<'de>, { let mut dynamic_map = DynamicMap::default(); - while let Some(key) = map.next_key_seed(ReflectDeserializer { + let key_type_info = get_type_info( + self.map_info.key_type_id(), + self.map_info.key_type_name(), + self.registry, + )?; + let value_type_info = get_type_info( + self.map_info.value_type_id(), + self.map_info.value_type_name(), + self.registry, + )?; + while let Some(key) = map.next_key_seed(TypedReflectDeserializer { + type_info: key_type_info, registry: self.registry, })? { - let value = map.next_value_seed(ReflectDeserializer { + let value = map.next_value_seed(TypedReflectDeserializer { + type_info: value_type_info, registry: self.registry, })?; dynamic_map.insert_boxed(key, value); @@ -390,221 +495,449 @@ impl<'a, 'de> Visitor<'de> for MapVisitor<'a> { } } -struct StructDeserializer<'a> { - registry: &'a TypeRegistry, -} - -impl<'a, 'de> DeserializeSeed<'de> for StructDeserializer<'a> { - type Value = DynamicStruct; - - fn deserialize(self, deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - deserializer.deserialize_map(StructVisitor { - registry: self.registry, - }) - } -} - -struct StructVisitor<'a> { +struct EnumVisitor<'a> { + enum_info: &'a EnumInfo, registry: &'a TypeRegistry, } -impl<'a, 'de> Visitor<'de> for StructVisitor<'a> { - type Value = DynamicStruct; +impl<'a, 'de> Visitor<'de> for EnumVisitor<'a> { + type Value = DynamicEnum; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - formatter.write_str("struct value") + formatter.write_str("reflected enum value") } fn visit_map(self, mut map: V) -> Result where V: MapAccess<'de>, { - let mut dynamic_struct = DynamicStruct::default(); - while let Some(key) = map.next_key::()? { - let value = map.next_value_seed(ReflectDeserializer { - registry: self.registry, - })?; - dynamic_struct.insert_boxed(&key, value); + let variant_name = map + .next_key::()? + .ok_or_else(|| Error::missing_field("the variant name of the enum"))?; + + let variant_info = self + .enum_info + .variant(&variant_name) + .ok_or_else(|| Error::custom(format_args!("unknown variant {}", variant_name)))?; + + let mut dynamic_enum = DynamicEnum::default(); + + match variant_info { + VariantInfo::Struct(struct_info) => { + let dynamic_struct = map.next_value_seed(StructVariantDeserializer { + struct_info, + registry: self.registry, + })?; + dynamic_enum.set_variant(variant_name, dynamic_struct); + } + VariantInfo::Tuple(tuple_info) => { + let dynamic_tuple = map.next_value_seed(TupleVariantDeserializer { + tuple_info, + registry: self.registry, + })?; + dynamic_enum.set_variant(variant_name, dynamic_tuple); + } + VariantInfo::Unit(..) => { + map.next_value::<()>()?; + dynamic_enum.set_variant(variant_name, ()); + } } - Ok(dynamic_struct) + Ok(dynamic_enum) } } -struct TupleStructDeserializer<'a> { +struct StructVariantDeserializer<'a> { + struct_info: &'a StructVariantInfo, registry: &'a TypeRegistry, } -impl<'a, 'de> DeserializeSeed<'de> for TupleStructDeserializer<'a> { - type Value = DynamicTupleStruct; +impl<'a, 'de> DeserializeSeed<'de> for StructVariantDeserializer<'a> { + type Value = DynamicStruct; fn deserialize(self, deserializer: D) -> Result where D: serde::Deserializer<'de>, { - deserializer.deserialize_seq(TupleStructVisitor { + deserializer.deserialize_map(StructVariantVisitor { + struct_info: self.struct_info, registry: self.registry, }) } } -struct TupleStructVisitor<'a> { +struct StructVariantVisitor<'a> { + struct_info: &'a StructVariantInfo, registry: &'a TypeRegistry, } -impl<'a, 'de> Visitor<'de> for TupleStructVisitor<'a> { - type Value = DynamicTupleStruct; +impl<'a, 'de> Visitor<'de> for StructVariantVisitor<'a> { + type Value = DynamicStruct; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - formatter.write_str("tuple struct value") + formatter.write_str("reflected struct variant value") } - fn visit_seq(self, mut seq: V) -> Result + fn visit_map(self, mut map: V) -> Result where - V: SeqAccess<'de>, + V: MapAccess<'de>, { - let mut tuple_struct = DynamicTupleStruct::default(); - while let Some(value) = seq.next_element_seed(ReflectDeserializer { - registry: self.registry, - })? { - tuple_struct.insert_boxed(value); - } - Ok(tuple_struct) + visit_struct(&mut map, self.struct_info, self.registry) } } -struct TupleDeserializer<'a> { +struct TupleVariantDeserializer<'a> { + tuple_info: &'a TupleVariantInfo, registry: &'a TypeRegistry, } -impl<'a, 'de> DeserializeSeed<'de> for TupleDeserializer<'a> { +impl<'a, 'de> DeserializeSeed<'de> for TupleVariantDeserializer<'a> { type Value = DynamicTuple; fn deserialize(self, deserializer: D) -> Result where D: serde::Deserializer<'de>, { - deserializer.deserialize_seq(TupleVisitor { - registry: self.registry, - }) + deserializer.deserialize_tuple( + self.tuple_info.field_len(), + TupleVariantVisitor { + tuple_info: self.tuple_info, + registry: self.registry, + }, + ) } } -struct TupleVisitor<'a> { +struct TupleVariantVisitor<'a> { + tuple_info: &'a TupleVariantInfo, registry: &'a TypeRegistry, } -impl<'a, 'de> Visitor<'de> for TupleVisitor<'a> { +impl<'a, 'de> Visitor<'de> for TupleVariantVisitor<'a> { type Value = DynamicTuple; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - formatter.write_str("tuple value") + formatter.write_str("reflected tuple variant value") } fn visit_seq(self, mut seq: V) -> Result where V: SeqAccess<'de>, { - let mut tuple = DynamicTuple::default(); - while let Some(value) = seq.next_element_seed(ReflectDeserializer { - registry: self.registry, - })? { - tuple.insert_boxed(value); + visit_tuple(&mut seq, self.tuple_info, self.registry) + } +} + +fn visit_struct<'de, T, V>( + map: &mut V, + info: &T, + registry: &TypeRegistry, +) -> Result +where + T: StructLikeInfo, + V: MapAccess<'de>, +{ + let mut dynamic_struct = DynamicStruct::default(); + while let Some(key) = map.next_key::()? { + let field = info.get_field(&key).ok_or_else(|| { + Error::custom(format_args!( + "no field named {} on struct {}", + key, + info.get_name(), + )) + })?; + let type_info = get_type_info(field.type_id(), field.type_name(), registry)?; + let value = map.next_value_seed(TypedReflectDeserializer { + type_info, + registry, + })?; + dynamic_struct.insert_boxed(&key, value); + } + + Ok(dynamic_struct) +} + +fn visit_tuple<'de, T, V>( + seq: &mut V, + info: &T, + registry: &TypeRegistry, +) -> Result +where + T: TupleLikeInfo, + V: SeqAccess<'de>, +{ + let mut tuple = DynamicTuple::default(); + let mut index = 0usize; + + let get_field_info = |index: usize| -> Result<&TypeInfo, V::Error> { + let field = info.get_field(index).ok_or_else(|| { + Error::custom(format_args!( + "no field at index {} on tuple {}", + index, + info.get_name(), + )) + })?; + get_type_info(field.type_id(), field.type_name(), registry) + }; + + while let Some(value) = seq.next_element_seed(TypedReflectDeserializer { + type_info: get_field_info(index)?, + registry, + })? { + tuple.insert_boxed(value); + index += 1; + if index >= info.get_field_len() { + break; } - Ok(tuple) } -} -struct EnumDeserializer<'a> { - registry: &'a TypeRegistry, -} - -impl<'a, 'de> DeserializeSeed<'de> for EnumDeserializer<'a> { - type Value = DynamicEnum; + let len = info.get_field_len(); - fn deserialize(self, deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - deserializer.deserialize_map(EnumVisitor { - registry: self.registry, - }) + if tuple.field_len() != len { + return Err(Error::invalid_length( + tuple.field_len(), + &len.to_string().as_str(), + )); } + + Ok(tuple) } -struct EnumVisitor<'a> { +fn get_type_info<'a, E: de::Error>( + type_id: TypeId, + type_name: &'a str, registry: &'a TypeRegistry, +) -> Result<&'a TypeInfo, E> { + let registration = registry.get(type_id).ok_or_else(|| { + de::Error::custom(format_args!("no registration found for type {}", type_name)) + })?; + Ok(registration.type_info()) } -impl<'a, 'de> Visitor<'de> for EnumVisitor<'a> { - type Value = DynamicEnum; +#[cfg(test)] +mod tests { + use std::f32::consts::PI; - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - formatter.write_str("enum value") + use serde::de::DeserializeSeed; + use serde::Deserialize; + + use bevy_utils::HashMap; + + use crate as bevy_reflect; + use crate::serde::{TypedReflectDeserializer, UntypedReflectDeserializer}; + use crate::{DynamicEnum, FromReflect, Reflect, ReflectDeserialize, TypeRegistry, Typed}; + + #[derive(Reflect, FromReflect, 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, + struct_value: SomeStruct, + tuple_struct_value: SomeTupleStruct, + unit_enum: SomeEnum, + newtype_enum: SomeEnum, + tuple_enum: SomeEnum, + struct_enum: SomeEnum, + custom_deserialize: CustomDeserialize, + } + + #[derive(Reflect, FromReflect, Debug, PartialEq)] + struct SomeStruct { + foo: i64, + } + + #[derive(Reflect, FromReflect, Debug, PartialEq)] + struct SomeTupleStruct(String); + + #[derive(Reflect, FromReflect, 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, FromReflect, Debug, PartialEq, Deserialize)] + #[reflect(Deserialize)] + struct CustomDeserialize { + value: usize, + #[serde(rename = "renamed")] + inner_struct: SomeDeserializableStruct, + } + + #[derive(Reflect, FromReflect, Debug, PartialEq)] + enum SomeEnum { + Unit, + NewType(usize), + Tuple(f32, f32), + Struct { foo: String }, } - fn visit_map(self, mut map: V) -> Result - where - V: MapAccess<'de>, - { - let key = map.next_key::()?; - match key.as_deref() { - Some(type_fields::VARIANT) => {} - Some(key) => return Err(V::Error::unknown_field(key, &[type_fields::VARIANT])), - _ => { - return Err(V::Error::missing_field(type_fields::VARIANT)); - } - } + 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::<(f32, usize)>(); + registry.register::<[i32; 5]>(); + registry.register::>(); + registry.register::>(); + registry.register::>(); + registry.register::>(); + registry.register_type_data::, ReflectDeserialize>(); + registry + } - let variant_name = map.next_value::()?; + #[test] + fn should_deserialize() { + let mut map = HashMap::new(); + map.insert(64, 32); + + let expected = 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, + struct_value: SomeStruct { foo: 999999999 }, + tuple_struct_value: SomeTupleStruct(String::from("Tuple Struct")), + 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"), + }, + custom_deserialize: CustomDeserialize { + value: 100, + inner_struct: SomeDeserializableStruct { foo: 101 }, + }, + }; - let mut dynamic_enum = DynamicEnum::default(); + 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, + }, + "struct_value": { + "foo": 999999999, + }, + "tuple_struct_value": ("Tuple Struct"), + "unit_enum": { + "Unit": (), + }, + "newtype_enum": { + "NewType": (123), + }, + "tuple_enum": { + "Tuple": (1.23, 3.21), + }, + "struct_enum": { + "Struct": { + "foo": "Struct variant value", + }, + }, + "custom_deserialize": ( + value: 100, + renamed: ( + foo: 101, + ), + ) + }, + }"#; - let key = map.next_key::()?; - match key.as_deref() { - Some(type_fields::STRUCT) => { - let dynamic_struct = map.next_value_seed(StructDeserializer { - registry: self.registry, - })?; - dynamic_enum.set_variant(variant_name, dynamic_struct); - } - Some(type_fields::TUPLE) => { - let dynamic_tuple = map.next_value_seed(TupleDeserializer { - registry: self.registry, - })?; - dynamic_enum.set_variant(variant_name, dynamic_tuple); - } - Some(invalid_key) => { - return Err(V::Error::unknown_field( - invalid_key, - &[type_fields::STRUCT, type_fields::TUPLE], - )); - } - None => dynamic_enum.set_variant(variant_name, ()), - } + let registry = get_registry(); + let reflect_deserializer = UntypedReflectDeserializer::new(®istry); + let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap(); + let dynamic_output = reflect_deserializer + .deserialize(&mut ron_deserializer) + .unwrap(); - Ok(dynamic_enum) + let output = ::from_reflect(dynamic_output.as_ref()).unwrap(); + assert_eq!(expected, output); } -} -#[cfg(test)] -mod tests { - use super::ReflectDeserializer; - use crate as bevy_reflect; - use crate::prelude::*; - use crate::{DynamicEnum, TypeRegistry}; - use ::serde::de::DeserializeSeed; + #[test] + fn should_deserialize_value() { + let input = r#"{ + "f32": 1.23, + }"#; - fn get_registry() -> TypeRegistry { - let mut registry = TypeRegistry::default(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::<(f32, f32)>(); - registry + let registry = get_registry(); + let reflect_deserializer = UntypedReflectDeserializer::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 + .take::() + .expect("underlying type should be f32"); + assert_eq!(1.23, output); + } + + #[test] + fn should_deserialized_typed() { + #[derive(Reflect, FromReflect, Debug, PartialEq)] + struct Foo { + bar: i32, + } + + let expected = Foo { bar: 123 }; + + let input = r#"{ + "bar": 123 + }"#; + + let mut registry = get_registry(); + registry.register::(); + let reflect_deserializer = TypedReflectDeserializer::new(Foo::type_info(), ®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] @@ -622,12 +955,11 @@ mod tests { // === Unit Variant === // let input = r#"{ - "type": "bevy_reflect::serde::de::tests::enum_should_deserialize::MyEnum", - "enum": { - "variant": "Unit", - }, -}"#; - let reflect_deserializer = ReflectDeserializer::new(®istry); + "bevy_reflect::serde::de::tests::enum_should_deserialize::MyEnum": { + "Unit": (), + }, + }"#; + let reflect_deserializer = UntypedReflectDeserializer::new(®istry); let mut deserializer = ron::de::Deserializer::from_str(input).unwrap(); let output = reflect_deserializer.deserialize(&mut deserializer).unwrap(); @@ -636,18 +968,11 @@ mod tests { // === NewType Variant === // let input = r#"{ - "type": "bevy_reflect::serde::de::tests::enum_should_deserialize::MyEnum", - "enum": { - "variant": "NewType", - "tuple": [ - { - "type": "usize", - "value": 123, + "bevy_reflect::serde::de::tests::enum_should_deserialize::MyEnum": { + "NewType": (123), }, - ], - }, -}"#; - let reflect_deserializer = ReflectDeserializer::new(®istry); + }"#; + let reflect_deserializer = UntypedReflectDeserializer::new(®istry); let mut deserializer = ron::de::Deserializer::from_str(input).unwrap(); let output = reflect_deserializer.deserialize(&mut deserializer).unwrap(); @@ -656,22 +981,11 @@ mod tests { // === Tuple Variant === // let input = r#"{ - "type": "bevy_reflect::serde::de::tests::enum_should_deserialize::MyEnum", - "enum": { - "variant": "Tuple", - "tuple": [ - { - "type": "f32", - "value": 1.23, - }, - { - "type": "f32", - "value": 3.21, + "bevy_reflect::serde::de::tests::enum_should_deserialize::MyEnum": { + "Tuple": (1.23, 3.21), }, - ], - }, -}"#; - let reflect_deserializer = ReflectDeserializer::new(®istry); + }"#; + let reflect_deserializer = UntypedReflectDeserializer::new(®istry); let mut deserializer = ron::de::Deserializer::from_str(input).unwrap(); let output = reflect_deserializer.deserialize(&mut deserializer).unwrap(); @@ -680,18 +994,13 @@ mod tests { // === Struct Variant === // let input = r#"{ - "type": "bevy_reflect::serde::de::tests::enum_should_deserialize::MyEnum", - "enum": { - "variant": "Struct", - "struct": { - "value": { - "type": "alloc::string::String", - "value": "I <3 Enums", + "bevy_reflect::serde::de::tests::enum_should_deserialize::MyEnum": { + "Struct": { + "value": "I <3 Enums", + }, }, - }, - }, -}"#; - let reflect_deserializer = ReflectDeserializer::new(®istry); + }"#; + let reflect_deserializer = UntypedReflectDeserializer::new(®istry); let mut deserializer = ron::de::Deserializer::from_str(input).unwrap(); let output = reflect_deserializer.deserialize(&mut deserializer).unwrap(); diff --git a/crates/bevy_reflect/src/serde/mod.rs b/crates/bevy_reflect/src/serde/mod.rs index 7c7c18f4ea954..21612b6c05553 100644 --- a/crates/bevy_reflect/src/serde/mod.rs +++ b/crates/bevy_reflect/src/serde/mod.rs @@ -3,16 +3,3 @@ mod ser; pub use de::*; pub use ser::*; - -pub(crate) mod type_fields { - pub const TYPE: &str = "type"; - pub const MAP: &str = "map"; - pub const STRUCT: &str = "struct"; - pub const TUPLE_STRUCT: &str = "tuple_struct"; - pub const ENUM: &str = "enum"; - pub const VARIANT: &str = "variant"; - pub const TUPLE: &str = "tuple"; - pub const LIST: &str = "list"; - pub const ARRAY: &str = "array"; - pub const VALUE: &str = "value"; -} diff --git a/crates/bevy_reflect/src/serde/ser.rs b/crates/bevy_reflect/src/serde/ser.rs index 0dd239d6305a7..de78ca77b6206 100644 --- a/crates/bevy_reflect/src/serde/ser.rs +++ b/crates/bevy_reflect/src/serde/ser.rs @@ -1,8 +1,8 @@ use crate::{ - serde::type_fields, Array, Enum, List, Map, Reflect, ReflectRef, ReflectSerialize, Struct, - Tuple, TupleStruct, TypeRegistry, VariantType, + Array, Enum, List, Map, Reflect, ReflectRef, ReflectSerialize, Struct, Tuple, TupleStruct, + TypeRegistry, VariantType, }; -use serde::ser::Error; +use serde::ser::SerializeTuple; use serde::{ ser::{SerializeMap, SerializeSeq}, Serialize, Serializer, @@ -38,6 +38,13 @@ fn get_serializable<'a, E: serde::ser::Error>( Ok(reflect_serialize.get_serializable(reflect_value)) } +/// A general purpose serializer for reflected types. +/// +/// The serialized data will take the form of a map containing the following entries: +/// 1. `type`: The _full_ [type name] +/// 2. `value`: The serialized value of the reflected type +/// +/// [type name]: std::any::type_name pub struct ReflectSerializer<'a> { pub value: &'a dyn Reflect, pub registry: &'a TypeRegistry, @@ -54,6 +61,39 @@ impl<'a> Serialize for ReflectSerializer<'a> { where S: serde::Serializer, { + let mut state = serializer.serialize_map(Some(1))?; + state.serialize_entry( + self.value.type_name(), + &TypedReflectSerializer::new(self.value, self.registry), + )?; + state.end() + } +} + +/// A serializer for reflected types whose type is known and does not require +/// serialization to include other metadata about it. +pub struct TypedReflectSerializer<'a> { + pub value: &'a dyn Reflect, + pub registry: &'a TypeRegistry, +} + +impl<'a> TypedReflectSerializer<'a> { + pub fn new(value: &'a dyn Reflect, 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, @@ -90,11 +130,7 @@ impl<'a> Serialize for ReflectSerializer<'a> { registry: self.registry, } .serialize(serializer), - ReflectRef::Value(value) => ReflectValueSerializer { - registry: self.registry, - value, - } - .serialize(serializer), + ReflectRef::Value(_) => Err(serializable.err().unwrap()), } } } @@ -109,13 +145,9 @@ impl<'a> Serialize for ReflectValueSerializer<'a> { where S: serde::Serializer, { - let mut state = serializer.serialize_map(Some(2))?; - state.serialize_entry(type_fields::TYPE, self.value.type_name())?; - state.serialize_entry( - type_fields::VALUE, - get_serializable::(self.value, self.registry)?.borrow(), - )?; - state.end() + get_serializable::(self.value, self.registry)? + .borrow() + .serialize(serializer) } } @@ -125,30 +157,6 @@ pub struct StructSerializer<'a> { } impl<'a> Serialize for StructSerializer<'a> { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - let mut state = serializer.serialize_map(Some(2))?; - - state.serialize_entry(type_fields::TYPE, self.struct_value.type_name())?; - state.serialize_entry( - type_fields::STRUCT, - &StructValueSerializer { - struct_value: self.struct_value, - registry: self.registry, - }, - )?; - state.end() - } -} - -pub struct StructValueSerializer<'a> { - pub struct_value: &'a dyn Struct, - pub registry: &'a TypeRegistry, -} - -impl<'a> Serialize for StructValueSerializer<'a> { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, @@ -156,7 +164,7 @@ impl<'a> Serialize for StructValueSerializer<'a> { let mut state = serializer.serialize_map(Some(self.struct_value.field_len()))?; for (index, value) in self.struct_value.iter_fields().enumerate() { let key = self.struct_value.name_at(index).unwrap(); - state.serialize_entry(key, &ReflectSerializer::new(value, self.registry))?; + state.serialize_entry(key, &TypedReflectSerializer::new(value, self.registry))?; } state.end() } @@ -172,33 +180,9 @@ impl<'a> Serialize for TupleStructSerializer<'a> { where S: serde::Serializer, { - let mut state = serializer.serialize_map(Some(2))?; - - state.serialize_entry(type_fields::TYPE, self.tuple_struct.type_name())?; - state.serialize_entry( - type_fields::TUPLE_STRUCT, - &TupleStructValueSerializer { - tuple_struct: self.tuple_struct, - registry: self.registry, - }, - )?; - state.end() - } -} - -pub struct TupleStructValueSerializer<'a> { - pub tuple_struct: &'a dyn TupleStruct, - pub registry: &'a TypeRegistry, -} - -impl<'a> Serialize for TupleStructValueSerializer<'a> { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - let mut state = serializer.serialize_seq(Some(self.tuple_struct.field_len()))?; + let mut state = serializer.serialize_tuple(self.tuple_struct.field_len())?; for value in self.tuple_struct.iter_fields() { - state.serialize_element(&ReflectSerializer::new(value, self.registry))?; + state.serialize_element(&TypedReflectSerializer::new(value, self.registry))?; } state.end() } @@ -214,11 +198,9 @@ impl<'a> Serialize for EnumSerializer<'a> { where S: serde::Serializer, { - let mut state = serializer.serialize_map(Some(2))?; - - state.serialize_entry(type_fields::TYPE, self.enum_value.type_name())?; + let mut state = serializer.serialize_map(Some(1))?; state.serialize_entry( - type_fields::ENUM, + self.enum_value.variant_name(), &EnumValueSerializer { enum_value: self.enum_value, registry: self.registry, @@ -238,36 +220,26 @@ impl<'a> Serialize for EnumValueSerializer<'a> { where S: serde::Serializer, { - let variant_type = self.enum_value.variant_type(); - let variant_name = self.enum_value.variant_name(); - - let mut state = if matches!(variant_type, VariantType::Unit) { - serializer.serialize_map(Some(1))? - } else { - serializer.serialize_map(Some(2))? - }; - - state.serialize_entry(type_fields::VARIANT, variant_name)?; - match self.enum_value.variant_type() { VariantType::Struct => { - state.serialize_key(type_fields::STRUCT)?; - state.serialize_value(&StructVariantSerializer { - enum_value: self.enum_value, - registry: self.registry, - })?; + let mut state = serializer.serialize_map(Some(self.enum_value.field_len()))?; + for field in self.enum_value.iter_fields() { + let key = field.name().expect("named field"); + let value = TypedReflectSerializer::new(field.value(), self.registry); + state.serialize_entry(key, &value)?; + } + state.end() } VariantType::Tuple => { - state.serialize_key(type_fields::TUPLE)?; - state.serialize_value(&TupleVariantSerializer { - enum_value: self.enum_value, - registry: self.registry, - })?; + let mut state = serializer.serialize_tuple(self.enum_value.field_len())?; + for field in self.enum_value.iter_fields() { + let value = TypedReflectSerializer::new(field.value(), self.registry); + state.serialize_element(&value)?; + } + state.end() } - _ => {} + VariantType::Unit => serializer.serialize_unit(), } - - state.end() } } @@ -281,10 +253,10 @@ impl<'a> Serialize for TupleVariantSerializer<'a> { where S: Serializer, { - let field_len = self.enum_value.field_len(); - let mut state = serializer.serialize_seq(Some(field_len))?; + let mut state = serializer.serialize_tuple(self.enum_value.field_len())?; for field in self.enum_value.iter_fields() { - state.serialize_element(&ReflectSerializer::new(field.value(), self.registry))?; + let value = TypedReflectSerializer::new(field.value(), self.registry); + state.serialize_element(&value)?; } state.end() } @@ -300,16 +272,11 @@ impl<'a> Serialize for StructVariantSerializer<'a> { where S: Serializer, { - let field_len = self.enum_value.field_len(); - let mut state = serializer.serialize_map(Some(field_len))?; - for (index, field) in self.enum_value.iter_fields().enumerate() { - let name = field.name().ok_or_else(|| { - S::Error::custom(format_args!( - "struct variant missing name for field at index {}", - index - )) - })?; - state.serialize_entry(name, &ReflectSerializer::new(field.value(), self.registry))?; + let mut state = serializer.serialize_map(Some(self.enum_value.field_len()))?; + for field in self.enum_value.iter_fields() { + let key = field.name().expect("named field"); + let value = TypedReflectSerializer::new(field.value(), self.registry); + state.serialize_entry(key, &value)?; } state.end() } @@ -325,33 +292,9 @@ impl<'a> Serialize for TupleSerializer<'a> { where S: serde::Serializer, { - let mut state = serializer.serialize_map(Some(2))?; - - state.serialize_entry(type_fields::TYPE, self.tuple.type_name())?; - state.serialize_entry( - type_fields::TUPLE, - &TupleValueSerializer { - tuple: self.tuple, - registry: self.registry, - }, - )?; - state.end() - } -} - -pub struct TupleValueSerializer<'a> { - pub tuple: &'a dyn Tuple, - pub registry: &'a TypeRegistry, -} - -impl<'a> Serialize for TupleValueSerializer<'a> { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - let mut state = serializer.serialize_seq(Some(self.tuple.field_len()))?; + let mut state = serializer.serialize_tuple(self.tuple.field_len())?; for value in self.tuple.iter_fields() { - state.serialize_element(&ReflectSerializer::new(value, self.registry))?; + state.serialize_element(&TypedReflectSerializer::new(value, self.registry))?; } state.end() } @@ -363,30 +306,6 @@ pub struct MapSerializer<'a> { } impl<'a> Serialize for MapSerializer<'a> { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - let mut state = serializer.serialize_map(Some(2))?; - - state.serialize_entry(type_fields::TYPE, self.map.type_name())?; - state.serialize_entry( - type_fields::MAP, - &MapValueSerializer { - map: self.map, - registry: self.registry, - }, - )?; - state.end() - } -} - -pub struct MapValueSerializer<'a> { - pub map: &'a dyn Map, - pub registry: &'a TypeRegistry, -} - -impl<'a> Serialize for MapValueSerializer<'a> { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, @@ -394,8 +313,8 @@ impl<'a> Serialize for MapValueSerializer<'a> { let mut state = serializer.serialize_map(Some(self.map.len()))?; for (key, value) in self.map.iter() { state.serialize_entry( - &ReflectSerializer::new(key, self.registry), - &ReflectSerializer::new(value, self.registry), + &TypedReflectSerializer::new(key, self.registry), + &TypedReflectSerializer::new(value, self.registry), )?; } state.end() @@ -408,36 +327,13 @@ pub struct ListSerializer<'a> { } impl<'a> Serialize for ListSerializer<'a> { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - let mut state = serializer.serialize_map(Some(2))?; - state.serialize_entry(type_fields::TYPE, self.list.type_name())?; - state.serialize_entry( - type_fields::LIST, - &ListValueSerializer { - list: self.list, - registry: self.registry, - }, - )?; - state.end() - } -} - -pub struct ListValueSerializer<'a> { - pub list: &'a dyn List, - pub registry: &'a TypeRegistry, -} - -impl<'a> Serialize for ListValueSerializer<'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(&ReflectSerializer::new(value, self.registry))?; + state.serialize_element(&TypedReflectSerializer::new(value, self.registry))?; } state.end() } @@ -453,32 +349,9 @@ impl<'a> Serialize for ArraySerializer<'a> { where S: serde::Serializer, { - let mut state = serializer.serialize_map(Some(2))?; - state.serialize_entry(type_fields::TYPE, self.array.type_name())?; - state.serialize_entry( - type_fields::ARRAY, - &ArrayValueSerializer { - array: self.array, - registry: self.registry, - }, - )?; - state.end() - } -} - -pub struct ArrayValueSerializer<'a> { - pub array: &'a dyn Array, - pub registry: &'a TypeRegistry, -} - -impl<'a> Serialize for ArrayValueSerializer<'a> { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - let mut state = serializer.serialize_seq(Some(self.array.len()))?; + let mut state = serializer.serialize_tuple(self.array.len())?; for value in self.array.iter() { - state.serialize_element(&ReflectSerializer::new(value, self.registry))?; + state.serialize_element(&TypedReflectSerializer::new(value, self.registry))?; } state.end() } @@ -486,21 +359,164 @@ impl<'a> Serialize for ArrayValueSerializer<'a> { #[cfg(test)] mod tests { - use super::ReflectSerializer; use crate as bevy_reflect; - use crate::prelude::*; - use crate::TypeRegistry; + use crate::serde::ReflectSerializer; + use crate::{FromReflect, Reflect, ReflectSerialize, TypeRegistry}; + use bevy_utils::HashMap; use ron::ser::PrettyConfig; + use serde::Serialize; + use std::f32::consts::PI; + + #[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, + struct_value: SomeStruct, + tuple_struct_value: SomeTupleStruct, + unit_enum: SomeEnum, + newtype_enum: SomeEnum, + tuple_enum: SomeEnum, + struct_enum: SomeEnum, + custom_serialize: CustomSerialize, + } + + #[derive(Reflect, FromReflect, Debug, PartialEq)] + struct SomeStruct { + foo: i64, + } + + #[derive(Reflect, Debug, PartialEq)] + struct SomeTupleStruct(String); + + #[derive(Reflect, Debug, PartialEq)] + enum SomeEnum { + Unit, + NewType(usize), + Tuple(f32, f32), + Struct { 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_type_data::(); registry.register::(); - registry.register::<(f32, f32)>(); + registry.register::>(); + registry.register_type_data::, ReflectSerialize>(); registry } + #[test] + fn should_serialize() { + let mut map = HashMap::new(); + map.insert(64, 32); + + let input = 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, + struct_value: SomeStruct { foo: 999999999 }, + tuple_struct_value: SomeTupleStruct(String::from("Tuple Struct")), + 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"), + }, + custom_serialize: CustomSerialize { + value: 100, + inner_struct: SomeSerializableStruct { foo: 101 }, + }, + }; + + let registry = get_registry(); + let serializer = ReflectSerializer::new(&input, ®istry); + + let config = PrettyConfig::default() + .new_line(String::from("\n")) + .decimal_floats(true) + .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, + }, + "struct_value": { + "foo": 999999999, + }, + "tuple_struct_value": ("Tuple Struct"), + "unit_enum": { + "Unit": (), + }, + "newtype_enum": { + "NewType": (123), + }, + "tuple_enum": { + "Tuple": (1.23, 3.21), + }, + "struct_enum": { + "Struct": { + "foo": "Struct variant value", + }, + }, + "custom_serialize": ( + value: 100, + renamed: ( + foo: 101, + ), + ), + }, +}"#; + assert_eq!(expected, output); + } + #[test] fn enum_should_serialize() { #[derive(Reflect)] @@ -521,9 +537,8 @@ mod tests { let serializer = ReflectSerializer::new(&value, ®istry); let output = ron::ser::to_string_pretty(&serializer, config.clone()).unwrap(); let expected = r#"{ - "type": "bevy_reflect::serde::ser::tests::enum_should_serialize::MyEnum", - "enum": { - "variant": "Unit", + "bevy_reflect::serde::ser::tests::enum_should_serialize::MyEnum": { + "Unit": (), }, }"#; assert_eq!(expected, output); @@ -533,15 +548,8 @@ mod tests { let serializer = ReflectSerializer::new(&value, ®istry); let output = ron::ser::to_string_pretty(&serializer, config.clone()).unwrap(); let expected = r#"{ - "type": "bevy_reflect::serde::ser::tests::enum_should_serialize::MyEnum", - "enum": { - "variant": "NewType", - "tuple": [ - { - "type": "usize", - "value": 123, - }, - ], + "bevy_reflect::serde::ser::tests::enum_should_serialize::MyEnum": { + "NewType": (123), }, }"#; assert_eq!(expected, output); @@ -551,19 +559,8 @@ mod tests { let serializer = ReflectSerializer::new(&value, ®istry); let output = ron::ser::to_string_pretty(&serializer, config.clone()).unwrap(); let expected = r#"{ - "type": "bevy_reflect::serde::ser::tests::enum_should_serialize::MyEnum", - "enum": { - "variant": "Tuple", - "tuple": [ - { - "type": "f32", - "value": 1.23, - }, - { - "type": "f32", - "value": 3.21, - }, - ], + "bevy_reflect::serde::ser::tests::enum_should_serialize::MyEnum": { + "Tuple": (1.23, 3.21), }, }"#; assert_eq!(expected, output); @@ -575,17 +572,12 @@ mod tests { let serializer = ReflectSerializer::new(&value, ®istry); let output = ron::ser::to_string_pretty(&serializer, config).unwrap(); let expected = r#"{ - "type": "bevy_reflect::serde::ser::tests::enum_should_serialize::MyEnum", - "enum": { - "variant": "Struct", - "struct": { - "value": { - "type": "alloc::string::String", - "value": "I <3 Enums", - }, + "bevy_reflect::serde::ser::tests::enum_should_serialize::MyEnum": { + "Struct": { + "value": "I <3 Enums", }, }, }"#; - assert_eq!(expected, output.replace('\r', "")); + assert_eq!(expected, output); } } diff --git a/crates/bevy_scene/src/serde.rs b/crates/bevy_scene/src/serde.rs index e55a5fd4b592b..8a3e5383af170 100644 --- a/crates/bevy_scene/src/serde.rs +++ b/crates/bevy_scene/src/serde.rs @@ -1,7 +1,7 @@ use crate::{DynamicEntity, DynamicScene}; use anyhow::Result; use bevy_reflect::{ - serde::{ReflectDeserializer, ReflectSerializer}, + serde::{ReflectSerializer, UntypedReflectDeserializer}, Reflect, TypeRegistry, TypeRegistryArc, }; use serde::{ @@ -242,7 +242,9 @@ impl<'a, 'de> Visitor<'de> for ComponentSeqVisitor<'a> { A: SeqAccess<'de>, { let mut dynamic_properties = Vec::new(); - while let Some(entity) = seq.next_element_seed(ReflectDeserializer::new(self.registry))? { + while let Some(entity) = + seq.next_element_seed(UntypedReflectDeserializer::new(self.registry))? + { dynamic_properties.push(entity); } diff --git a/examples/reflection/reflection.rs b/examples/reflection/reflection.rs index ca93c76b7f71d..447db38a3e743 100644 --- a/examples/reflection/reflection.rs +++ b/examples/reflection/reflection.rs @@ -7,7 +7,7 @@ use bevy::{ prelude::*, reflect::{ - serde::{ReflectDeserializer, ReflectSerializer}, + serde::{ReflectSerializer, UntypedReflectDeserializer}, DynamicStruct, }, }; @@ -81,7 +81,7 @@ fn setup(type_registry: Res) { info!("{}\n", ron_string); // Dynamic properties can be deserialized - let reflect_deserializer = ReflectDeserializer::new(&type_registry); + let reflect_deserializer = UntypedReflectDeserializer::new(&type_registry); let mut deserializer = ron::de::Deserializer::from_str(&ron_string).unwrap(); let reflect_value = reflect_deserializer.deserialize(&mut deserializer).unwrap();