From a02acfeebfba19e636b79bd00cd5b0613ad1f0c4 Mon Sep 17 00:00:00 2001 From: Ida Iyes Date: Sun, 21 Aug 2022 17:12:34 +0300 Subject: [PATCH] Revert "Pr #5723" This reverts commit 1ddf870b85c2f2e73f8f9cb00bc1252bf29b7558. --- assets/scenes/load_scene_example.scn.ron | 68 +- .../bevy_reflect_derive/src/impls/enums.rs | 3 +- .../bevy_reflect_derive/src/impls/structs.rs | 3 +- .../src/impls/tuple_structs.rs | 3 +- crates/bevy_reflect/src/enums/enum_trait.rs | 34 +- crates/bevy_reflect/src/enums/variants.rs | 87 +- crates/bevy_reflect/src/fields.rs | 9 +- crates/bevy_reflect/src/impls/glam.rs | 26 +- crates/bevy_reflect/src/impls/std.rs | 13 +- crates/bevy_reflect/src/lib.rs | 50 +- crates/bevy_reflect/src/serde/de.rs | 1265 ++++++----------- crates/bevy_reflect/src/serde/mod.rs | 13 + crates/bevy_reflect/src/serde/ser.rs | 714 ++++------ crates/bevy_reflect/src/struct_trait.rs | 29 +- crates/bevy_reflect/src/tuple_struct.rs | 14 +- crates/bevy_reflect/src/type_info.rs | 2 +- crates/bevy_reflect/src/utility.rs | 4 +- crates/bevy_scene/src/serde.rs | 6 +- examples/reflection/reflection.rs | 2 +- 19 files changed, 892 insertions(+), 1453 deletions(-) diff --git a/assets/scenes/load_scene_example.scn.ron b/assets/scenes/load_scene_example.scn.ron index 015b41774f3c07..1f9de9dae7da87 100644 --- a/assets/scenes/load_scene_example.scn.ron +++ b/assets/scenes/load_scene_example.scn.ron @@ -3,30 +3,43 @@ entity: 0, components: [ { - "bevy_transform::components::transform::Transform": ( - translation: ( - x: 0.0, - y: 0.0, - z: 0.0 - ), - rotation: (0.0, 0.0, 0.0, 1.0), - scale: ( - x: 1.0, - y: 1.0, - z: 1.0 - ), - ), + "type": "bevy_transform::components::transform::Transform", + "struct": { + "translation": { + "type": "glam::vec3::Vec3", + "value": (0.0, 0.0, 0.0), + }, + "rotation": { + "type": "glam::quat::Quat", + "value": (0.0, 0.0, 0.0, 1.0), + }, + "scale": { + "type": "glam::vec3::Vec3", + "value": (1.0, 1.0, 1.0), + }, + }, }, { - "scene::ComponentB": ( - value: "hello", - ), + "type": "scene::ComponentB", + "struct": { + "value": { + "type": "alloc::string::String", + "value": "hello", + }, + }, }, { - "scene::ComponentA": ( - x: 1.0, - y: 2.0, - ), + "type": "scene::ComponentA", + "struct": { + "x": { + "type": "f32", + "value": 1.0, + }, + "y": { + "type": "f32", + "value": 2.0, + }, + }, }, ], ), @@ -34,10 +47,17 @@ entity: 1, components: [ { - "scene::ComponentA": ( - x: 3.0, - y: 4.0, - ), + "type": "scene::ComponentA", + "struct": { + "x": { + "type": "f32", + "value": 3.0, + }, + "y": { + "type": "f32", + "value": 4.0, + }, + }, }, ], ), diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/impls/enums.rs b/crates/bevy_reflect/bevy_reflect_derive/src/impls/enums.rs index 843b97ab3d3fa9..6140f853eee691 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/impls/enums.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/impls/enums.rs @@ -53,13 +53,12 @@ pub(crate) fn impl_enum(reflect_enum: &ReflectEnum) -> TokenStream { } }); - let string_name = enum_name.to_string(); let typed_impl = impl_typed( enum_name, reflect_enum.meta().generics(), quote! { let variants = [#(#variant_info),*]; - let info = #bevy_reflect_path::EnumInfo::new::(#string_name, &variants); + let info = #bevy_reflect_path::EnumInfo::new::(&variants); #bevy_reflect_path::TypeInfo::Enum(info) }, bevy_reflect_path, diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/impls/structs.rs b/crates/bevy_reflect/bevy_reflect_derive/src/impls/structs.rs index 29c66370009103..4dca3a4feea16f 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/impls/structs.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/impls/structs.rs @@ -51,7 +51,6 @@ pub(crate) fn impl_struct(reflect_struct: &ReflectStruct) -> TokenStream { } }); - let string_name = struct_name.to_string(); let typed_impl = impl_typed( struct_name, reflect_struct.meta().generics(), @@ -59,7 +58,7 @@ pub(crate) fn impl_struct(reflect_struct: &ReflectStruct) -> TokenStream { let fields = [ #(#bevy_reflect_path::NamedField::new::<#field_types, _>(#field_names),)* ]; - let info = #bevy_reflect_path::StructInfo::new::(#string_name, &fields); + let info = #bevy_reflect_path::StructInfo::new::(&fields); #bevy_reflect_path::TypeInfo::Struct(info) }, bevy_reflect_path, diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/impls/tuple_structs.rs b/crates/bevy_reflect/bevy_reflect_derive/src/impls/tuple_structs.rs index 156ecfb9f87166..0ad33ba4bb8ce8 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/impls/tuple_structs.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/impls/tuple_structs.rs @@ -35,7 +35,6 @@ pub(crate) fn impl_tuple_struct(reflect_struct: &ReflectStruct) -> TokenStream { } }); - let string_name = struct_name.to_string(); let typed_impl = impl_typed( struct_name, reflect_struct.meta().generics(), @@ -43,7 +42,7 @@ pub(crate) fn impl_tuple_struct(reflect_struct: &ReflectStruct) -> TokenStream { let fields = [ #(#bevy_reflect_path::UnnamedField::new::<#field_types>(#field_idents),)* ]; - let info = #bevy_reflect_path::TupleStructInfo::new::(#string_name, &fields); + let info = #bevy_reflect_path::TupleStructInfo::new::(&fields); #bevy_reflect_path::TypeInfo::TupleStruct(info) }, bevy_reflect_path, diff --git a/crates/bevy_reflect/src/enums/enum_trait.rs b/crates/bevy_reflect/src/enums/enum_trait.rs index 12e017dc53877d..9ee110d8f0a05e 100644 --- a/crates/bevy_reflect/src/enums/enum_trait.rs +++ b/crates/bevy_reflect/src/enums/enum_trait.rs @@ -1,6 +1,7 @@ use crate::{DynamicEnum, Reflect, VariantInfo, VariantType}; use bevy_utils::HashMap; use std::any::{Any, TypeId}; +use std::borrow::Cow; use std::slice::Iter; /// A trait representing a [reflected] enum. @@ -130,12 +131,10 @@ pub trait Enum: Reflect { /// A container for compile-time enum info, used by [`TypeInfo`](crate::TypeInfo). #[derive(Clone, Debug)] pub struct EnumInfo { - name: &'static str, type_name: &'static str, type_id: TypeId, variants: Box<[VariantInfo]>, - variant_names: Box<[&'static str]>, - variant_indices: HashMap<&'static str, usize>, + variant_indices: HashMap, usize>, } impl EnumInfo { @@ -143,27 +142,22 @@ impl EnumInfo { /// /// # Arguments /// - /// * `name`: The name of this enum (_without_ generics or lifetimes) /// * `variants`: The variants of this enum in the order they are defined /// - pub fn new(name: &'static str, variants: &[VariantInfo]) -> Self { + pub fn new(variants: &[VariantInfo]) -> Self { let variant_indices = variants .iter() .enumerate() - .map(|(index, variant)| (variant.name(), index)) + .map(|(index, variant)| { + let name = variant.name().clone(); + (name, index) + }) .collect::>(); - let variant_names = variants - .iter() - .map(|variant| variant.name()) - .collect::>(); - Self { - name, type_name: std::any::type_name::(), type_id: TypeId::of::(), variants: variants.to_vec().into_boxed_slice(), - variant_names: variant_names.into_boxed_slice(), variant_indices, } } @@ -175,11 +169,6 @@ impl EnumInfo { .map(|index| &self.variants[*index]) } - /// A slice containing the names of all variants in order. - pub fn variant_names(&self) -> &[&'static str] { - &self.variant_names - } - /// Get a variant at the given index. pub fn variant_at(&self, index: usize) -> Option<&VariantInfo> { self.variants.get(index) @@ -212,15 +201,6 @@ impl EnumInfo { self.variants.len() } - /// The name of the enum. - /// - /// This does _not_ include any generics or lifetimes. - /// - /// For example, `foo::bar::Baz<'a, T>` would simply be `Baz`. - pub fn name(&self) -> &'static str { - self.name - } - /// The [type name] of the enum. /// /// [type name]: std::any::type_name diff --git a/crates/bevy_reflect/src/enums/variants.rs b/crates/bevy_reflect/src/enums/variants.rs index d748eac3c50d56..b1a9740d21c751 100644 --- a/crates/bevy_reflect/src/enums/variants.rs +++ b/crates/bevy_reflect/src/enums/variants.rs @@ -1,5 +1,6 @@ use crate::{NamedField, UnnamedField}; use bevy_utils::HashMap; +use std::borrow::Cow; use std::slice::Iter; /// Describes the form of an enum variant. @@ -65,7 +66,7 @@ pub enum VariantInfo { } impl VariantInfo { - pub fn name(&self) -> &'static str { + pub fn name(&self) -> &Cow<'static, str> { match self { Self::Struct(info) => info.name(), Self::Tuple(info) => info.name(), @@ -77,28 +78,39 @@ impl VariantInfo { /// Type info for struct variants. #[derive(Clone, Debug)] pub struct StructVariantInfo { - name: &'static str, + name: Cow<'static, str>, fields: Box<[NamedField]>, - field_names: Box<[&'static str]>, - field_indices: HashMap<&'static str, usize>, + field_indices: HashMap, usize>, } impl StructVariantInfo { /// Create a new [`StructVariantInfo`]. - pub fn new(name: &'static str, fields: &[NamedField]) -> Self { + pub fn new(name: &str, fields: &[NamedField]) -> Self { + let field_indices = Self::collect_field_indices(fields); + + Self { + name: Cow::Owned(name.into()), + fields: fields.to_vec().into_boxed_slice(), + field_indices, + } + } + + /// Create a new [`StructVariantInfo`] using a static string. + /// + /// This helps save an allocation when the string has a static lifetime, such + /// as when using defined sa a literal. + pub fn new_static(name: &'static str, fields: &[NamedField]) -> Self { let field_indices = Self::collect_field_indices(fields); - let field_names = fields.iter().map(|field| field.name()).collect::>(); Self { - name, + name: Cow::Borrowed(name), fields: fields.to_vec().into_boxed_slice(), - field_names: field_names.into_boxed_slice(), field_indices, } } /// The name of this variant. - pub fn name(&self) -> &'static str { - self.name + pub fn name(&self) -> &Cow<'static, str> { + &self.name } /// Get the field with the given name. @@ -108,11 +120,6 @@ impl StructVariantInfo { .map(|index| &self.fields[*index]) } - /// A slice containing the names of all fields in order. - pub fn field_names(&self) -> &[&'static str] { - &self.field_names - } - /// Get the field at the given index. pub fn field_at(&self, index: usize) -> Option<&NamedField> { self.fields.get(index) @@ -133,11 +140,14 @@ impl StructVariantInfo { self.fields.len() } - fn collect_field_indices(fields: &[NamedField]) -> HashMap<&'static str, usize> { + fn collect_field_indices(fields: &[NamedField]) -> HashMap, usize> { fields .iter() .enumerate() - .map(|(index, field)| (field.name(), index)) + .map(|(index, field)| { + let name = field.name().clone(); + (name, index) + }) .collect() } } @@ -145,22 +155,33 @@ impl StructVariantInfo { /// Type info for tuple variants. #[derive(Clone, Debug)] pub struct TupleVariantInfo { - name: &'static str, + name: Cow<'static, str>, fields: Box<[UnnamedField]>, } impl TupleVariantInfo { /// Create a new [`TupleVariantInfo`]. - pub fn new(name: &'static str, fields: &[UnnamedField]) -> Self { + pub fn new(name: &str, fields: &[UnnamedField]) -> Self { + Self { + name: Cow::Owned(name.into()), + fields: fields.to_vec().into_boxed_slice(), + } + } + + /// Create a new [`TupleVariantInfo`] using a static string. + /// + /// This helps save an allocation when the string has a static lifetime, such + /// as when using defined sa a literal. + pub fn new_static(name: &'static str, fields: &[UnnamedField]) -> Self { Self { - name, + name: Cow::Borrowed(name), fields: fields.to_vec().into_boxed_slice(), } } /// The name of this variant. - pub fn name(&self) -> &'static str { - self.name + pub fn name(&self) -> &Cow<'static, str> { + &self.name } /// Get the field at the given index. @@ -182,17 +203,29 @@ impl TupleVariantInfo { /// Type info for unit variants. #[derive(Clone, Debug)] pub struct UnitVariantInfo { - name: &'static str, + name: Cow<'static, str>, } impl UnitVariantInfo { /// Create a new [`UnitVariantInfo`]. - pub fn new(name: &'static str) -> Self { - Self { name } + pub fn new(name: &str) -> Self { + Self { + name: Cow::Owned(name.into()), + } + } + + /// Create a new [`UnitVariantInfo`] using a static string. + /// + /// This helps save an allocation when the string has a static lifetime, such + /// as when using defined sa a literal. + pub fn new_static(name: &'static str) -> Self { + Self { + name: Cow::Borrowed(name), + } } /// The name of this variant. - pub fn name(&self) -> &'static str { - self.name + pub fn name(&self) -> &Cow<'static, str> { + &self.name } } diff --git a/crates/bevy_reflect/src/fields.rs b/crates/bevy_reflect/src/fields.rs index a752fb1fab731f..21dc9ec5f75e20 100644 --- a/crates/bevy_reflect/src/fields.rs +++ b/crates/bevy_reflect/src/fields.rs @@ -1,17 +1,18 @@ use crate::Reflect; use std::any::{Any, TypeId}; +use std::borrow::Cow; /// The named field of a reflected struct. #[derive(Clone, Debug)] pub struct NamedField { - name: &'static str, + name: Cow<'static, str>, type_name: &'static str, type_id: TypeId, } impl NamedField { /// Create a new [`NamedField`]. - pub fn new>(name: TName) -> Self { + pub fn new>>(name: TName) -> Self { Self { name: name.into(), type_name: std::any::type_name::(), @@ -20,8 +21,8 @@ impl NamedField { } /// The name of the field. - pub fn name(&self) -> &'static str { - self.name + pub fn name(&self) -> &Cow<'static, str> { + &self.name } /// The [type name] of the field. diff --git a/crates/bevy_reflect/src/impls/glam.rs b/crates/bevy_reflect/src/impls/glam.rs index 9dfcc8293ce235..c84fcbffaaf270 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, Default)] + #[reflect(Debug, PartialEq, Serialize, Deserialize, Default)] struct IVec2 { x: i32, y: i32, } ); impl_reflect_struct!( - #[reflect(Debug, PartialEq, Default)] + #[reflect(Debug, PartialEq, Serialize, Deserialize, Default)] struct IVec3 { x: i32, y: i32, @@ -21,7 +21,7 @@ impl_reflect_struct!( } ); impl_reflect_struct!( - #[reflect(Debug, PartialEq, Default)] + #[reflect(Debug, PartialEq, Serialize, Deserialize, Default)] struct IVec4 { x: i32, y: i32, @@ -31,14 +31,14 @@ impl_reflect_struct!( ); impl_reflect_struct!( - #[reflect(Debug, PartialEq, Default)] + #[reflect(Debug, PartialEq, Serialize, Deserialize, Default)] struct UVec2 { x: u32, y: u32, } ); impl_reflect_struct!( - #[reflect(Debug, PartialEq, Default)] + #[reflect(Debug, PartialEq, Serialize, Deserialize, Default)] struct UVec3 { x: u32, y: u32, @@ -46,7 +46,7 @@ impl_reflect_struct!( } ); impl_reflect_struct!( - #[reflect(Debug, PartialEq, Default)] + #[reflect(Debug, PartialEq, Serialize, Deserialize, Default)] struct UVec4 { x: u32, y: u32, @@ -56,14 +56,14 @@ impl_reflect_struct!( ); impl_reflect_struct!( - #[reflect(Debug, PartialEq, Default)] + #[reflect(Debug, PartialEq, Serialize, Deserialize, Default)] struct Vec2 { x: f32, y: f32, } ); impl_reflect_struct!( - #[reflect(Debug, PartialEq, Default)] + #[reflect(Debug, PartialEq, Serialize, Deserialize, Default)] struct Vec3 { x: f32, y: f32, @@ -71,7 +71,7 @@ impl_reflect_struct!( } ); impl_reflect_struct!( - #[reflect(Debug, PartialEq, Default)] + #[reflect(Debug, PartialEq, Serialize, Deserialize, Default)] struct Vec3A { x: f32, y: f32, @@ -79,7 +79,7 @@ impl_reflect_struct!( } ); impl_reflect_struct!( - #[reflect(Debug, PartialEq, Default)] + #[reflect(Debug, PartialEq, Serialize, Deserialize, Default)] struct Vec4 { x: f32, y: f32, @@ -114,14 +114,14 @@ impl_reflect_struct!( ); impl_reflect_struct!( - #[reflect(Debug, PartialEq, Default)] + #[reflect(Debug, PartialEq, Serialize, Deserialize, Default)] struct DVec2 { x: f64, y: f64, } ); impl_reflect_struct!( - #[reflect(Debug, PartialEq, Default)] + #[reflect(Debug, PartialEq, Serialize, Deserialize, Default)] struct DVec3 { x: f64, y: f64, @@ -129,7 +129,7 @@ impl_reflect_struct!( } ); impl_reflect_struct!( - #[reflect(Debug, PartialEq, Default)] + #[reflect(Debug, PartialEq, Serialize, Deserialize, Default)] struct DVec4 { x: f64, y: f64, diff --git a/crates/bevy_reflect/src/impls/std.rs b/crates/bevy_reflect/src/impls/std.rs index 4d9865167b7ba0..7b66aba360249c 100644 --- a/crates/bevy_reflect/src/impls/std.rs +++ b/crates/bevy_reflect/src/impls/std.rs @@ -787,13 +787,12 @@ impl Typed for Option { fn type_info() -> &'static TypeInfo { static CELL: GenericTypeInfoCell = GenericTypeInfoCell::new(); CELL.get_or_insert::(|| { - let none_variant = VariantInfo::Unit(UnitVariantInfo::new("None")); - let some_variant = - VariantInfo::Tuple(TupleVariantInfo::new("Some", &[UnnamedField::new::(0)])); - TypeInfo::Enum(EnumInfo::new::( - "Option", - &[none_variant, some_variant], - )) + let none_variant = VariantInfo::Unit(UnitVariantInfo::new_static("None")); + let some_variant = VariantInfo::Tuple(TupleVariantInfo::new_static( + "Some", + &[UnnamedField::new::(0)], + )); + TypeInfo::Enum(EnumInfo::new::(&[none_variant, some_variant])) }) } } diff --git a/crates/bevy_reflect/src/lib.rs b/crates/bevy_reflect/src/lib.rs index 71d2572112328c..ef9e05ccd3cffb 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, Deserialize, Serialize}; + use ::serde::de::DeserializeSeed; 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::{ReflectSerializer, UntypedReflectDeserializer}; + use crate::serde::{ReflectDeserializer, ReflectSerializer}; #[test] fn reflect_struct() { @@ -451,8 +451,7 @@ mod tests { h: [u32; 2], } - #[derive(Reflect, Serialize, Deserialize)] - #[reflect(Serialize, Deserialize)] + #[derive(Reflect)] struct Bar { x: u32, } @@ -473,23 +472,18 @@ 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::<(i32, Vec, Bar)>(); - registry.register::<[u32; 2]>(); + registry.register::(); + registry.register::(); 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 = UntypedReflectDeserializer::new(®istry); + let reflect_deserializer = ReflectDeserializer::new(®istry); let value = reflect_deserializer.deserialize(&mut deserializer).unwrap(); let dynamic_struct = value.take::().unwrap(); @@ -935,39 +929,23 @@ bevy_reflect::tests::should_reflect_debug::Test { let ser = ReflectSerializer::new(&v, ®istry); - 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, - ), -}"#; + let result = ron::to_string(&ser).expect("Failed to serialize to string"); - assert_eq!(expected, format!("\n{}", output)); + 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}}}"# + ); } #[test] fn vec3_deserialization() { - let data = r#" -{ - "glam::f32::vec3::Vec3": ( - x: 12.0, - y: 3.0, - z: -6.9, - ), -}"#; + 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 mut registry = TypeRegistry::default(); registry.add_registration(Vec3::get_type_registration()); registry.add_registration(f32::get_type_registration()); - let de = UntypedReflectDeserializer::new(®istry); + let de = ReflectDeserializer::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 da7e2c2248ff17..ad24185de15f3f 100644 --- a/crates/bevy_reflect/src/serde/de.rs +++ b/crates/bevy_reflect/src/serde/de.rs @@ -1,17 +1,9 @@ use crate::{ - ArrayInfo, DynamicArray, DynamicEnum, DynamicList, DynamicMap, DynamicStruct, DynamicTuple, - DynamicTupleStruct, DynamicVariant, EnumInfo, ListInfo, Map, MapInfo, NamedField, Reflect, - ReflectDeserialize, StructInfo, StructVariantInfo, Tuple, TupleInfo, TupleStruct, - TupleStructInfo, TupleVariantInfo, TypeInfo, TypeRegistry, UnnamedField, VariantInfo, + serde::type_fields, DynamicArray, DynamicEnum, DynamicList, DynamicMap, DynamicStruct, + DynamicTuple, DynamicTupleStruct, Map, Reflect, ReflectDeserialize, TypeRegistry, }; use erased_serde::Deserializer; -use serde::de::{ - self, DeserializeSeed, EnumAccess, Error, MapAccess, SeqAccess, VariantAccess, Visitor, -}; -use serde::Deserialize; -use std::any::TypeId; -use std::fmt; -use std::fmt::Formatter; +use serde::de::{self, DeserializeSeed, Error, MapAccess, SeqAccess, Visitor}; pub trait DeserializeValue { fn deserialize( @@ -20,444 +12,321 @@ pub trait DeserializeValue { ) -> Result, erased_serde::Error>; } -trait StructLikeInfo { - fn get_name(&self) -> &str; - fn get_field(&self, name: &str) -> Option<&NamedField>; - fn get_field_names(&self) -> &[&'static str]; +pub struct ReflectDeserializer<'a> { + registry: &'a TypeRegistry, } -trait TupleLikeInfo { - fn get_name(&self) -> &str; - fn get_field(&self, index: usize) -> Option<&UnnamedField>; - fn get_field_len(&self) -> usize; +impl<'a> ReflectDeserializer<'a> { + pub fn new(registry: &'a TypeRegistry) -> Self { + ReflectDeserializer { registry } + } } -impl StructLikeInfo for StructInfo { - fn get_name(&self) -> &str { - self.type_name() - } +impl<'a, 'de> DeserializeSeed<'de> for ReflectDeserializer<'a> { + type Value = Box; - fn get_field(&self, name: &str) -> Option<&NamedField> { - self.field(name) + fn deserialize(self, deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + deserializer.deserialize_any(ReflectVisitor { + registry: self.registry, + }) } +} - fn get_field_names(&self) -> &[&'static str] { - self.field_names() - } +struct ReflectVisitor<'a> { + registry: &'a TypeRegistry, } -impl StructLikeInfo for StructVariantInfo { - fn get_name(&self) -> &str { - self.name() - } +impl<'a, 'de> Visitor<'de> for ReflectVisitor<'a> { + type Value = Box; - fn get_field(&self, name: &str) -> Option<&NamedField> { - self.field(name) + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("reflect value") } - fn get_field_names(&self) -> &[&'static str] { - self.field_names() + fn visit_u8(self, v: u8) -> Result + where + E: de::Error, + { + Ok(Box::new(v)) } -} -impl TupleLikeInfo for TupleInfo { - fn get_name(&self) -> &str { - self.type_name() + fn visit_bool(self, v: bool) -> Result + where + E: de::Error, + { + Ok(Box::new(v)) } - fn get_field(&self, index: usize) -> Option<&UnnamedField> { - self.field_at(index) + fn visit_u16(self, v: u16) -> Result + where + E: de::Error, + { + Ok(Box::new(v)) } - fn get_field_len(&self) -> usize { - self.field_len() + fn visit_u32(self, v: u32) -> Result + where + E: de::Error, + { + Ok(Box::new(v)) } -} -impl TupleLikeInfo for TupleVariantInfo { - fn get_name(&self) -> &str { - self.name() + fn visit_u64(self, v: u64) -> Result + where + E: de::Error, + { + Ok(Box::new(v)) } - fn get_field(&self, index: usize) -> Option<&UnnamedField> { - self.field_at(index) + fn visit_i8(self, v: i8) -> Result + where + E: de::Error, + { + Ok(Box::new(v)) } - fn get_field_len(&self) -> usize { - self.field_len() + fn visit_i16(self, v: i16) -> Result + where + E: de::Error, + { + Ok(Box::new(v)) } -} - -/// Represents a simple reflected identifier. -#[derive(Debug, Clone, Eq, PartialEq)] -struct Ident(String); -impl<'de> Deserialize<'de> for Ident { - fn deserialize(deserializer: D) -> Result + fn visit_i32(self, v: i32) -> Result where - D: serde::Deserializer<'de>, + E: de::Error, { - struct IdentVisitor; - - impl<'de> Visitor<'de> for IdentVisitor { - type Value = Ident; - - fn expecting(&self, formatter: &mut fmt::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) + 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, -} - -impl<'a> UntypedReflectDeserializer<'a> { - pub fn new(registry: &'a TypeRegistry) -> Self { - Self { registry } + fn visit_i64(self, v: i64) -> Result + where + E: de::Error, + { + Ok(Box::new(v)) } -} -impl<'a, 'de> DeserializeSeed<'de> for UntypedReflectDeserializer<'a> { - type Value = Box; - - fn deserialize(self, deserializer: D) -> Result + fn visit_f32(self, v: f32) -> Result where - D: serde::Deserializer<'de>, + E: de::Error, { - deserializer.deserialize_any(UntypedReflectDeserializerVisitor { - registry: self.registry, - }) + Ok(Box::new(v)) } -} - -struct UntypedReflectDeserializerVisitor<'a> { - registry: &'a TypeRegistry, -} - -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_f64(self, v: f64) -> Result + where + E: de::Error, + { + Ok(Box::new(v)) } - fn visit_map(self, mut map: A) -> Result + fn visit_string(self, v: String) -> Result where - A: MapAccess<'de>, + E: de::Error, { - let type_name = map - .next_key::<&str>()? - .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) + Ok(Box::new(v)) } -} - -/// 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: &'static TypeInfo, - registry: &'a TypeRegistry, -} -impl<'a> TypedReflectDeserializer<'a> { - pub fn new(type_info: &'static TypeInfo, registry: &'a TypeRegistry) -> Self { - Self { - type_info, - registry, - } + fn visit_str(self, v: &str) -> Result + where + E: de::Error, + { + Ok(Box::new(v.to_string())) } -} - -impl<'a, 'de> DeserializeSeed<'de> for TypedReflectDeserializer<'a> { - type Value = Box; - fn deserialize(self, deserializer: D) -> Result + fn visit_map(self, mut map: V) -> Result where - D: serde::Deserializer<'de>, + V: MapAccess<'de>, { - // 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_struct( - struct_info.name(), - struct_info.field_names(), - StructVisitor { - struct_info, + 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, - }, - )?; - 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_struct( - tuple_struct_info.name(), - tuple_struct_info.field_len(), - TupleStructVisitor { - tuple_struct_info, + })?; + 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_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, + })?; + 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, - }, - )?; - 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, + })?; + 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, - }, - )?; - dynamic_tuple.set_name(tuple_info.type_name().to_string()); - Ok(Box::new(dynamic_tuple)) - } - TypeInfo::Enum(enum_info) => { - let type_name = enum_info.type_name(); - let mut dynamic_enum = if type_name.starts_with("core::option::Option") { - deserializer.deserialize_option(OptionVisitor { - enum_info, + })?; + 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, - })? - } else { - deserializer.deserialize_enum( - enum_info.name(), - enum_info.variant_names(), - EnumVisitor { - enum_info, - registry: self.registry, - }, - )? - }; - dynamic_enum.set_name(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 - ))) + })?; + 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\'")) } } -struct StructVisitor<'a> { - struct_info: &'static StructInfo, - registry: &'a TypeRegistry, +struct DeserializeReflectDeserializer<'a> { + reflect_deserialize: &'a ReflectDeserialize, } -impl<'a, 'de> Visitor<'de> for StructVisitor<'a> { - type Value = DynamicStruct; +impl<'a, 'de> DeserializeSeed<'de> for DeserializeReflectDeserializer<'a> { + type Value = Box; - fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result { - formatter.write_str("reflected struct value") + fn deserialize(self, deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + self.reflect_deserialize.deserialize(deserializer) } +} - fn visit_map(self, mut map: V) -> Result +struct ListDeserializer<'a> { + registry: &'a TypeRegistry, +} + +impl<'a, 'de> DeserializeSeed<'de> for ListDeserializer<'a> { + type Value = DynamicList; + + fn deserialize(self, deserializer: D) -> Result where - V: MapAccess<'de>, + D: serde::Deserializer<'de>, { - visit_struct(&mut map, self.struct_info, self.registry) + deserializer.deserialize_seq(ListVisitor { + registry: self.registry, + }) } } -struct TupleStructVisitor<'a> { - tuple_struct_info: &'static TupleStructInfo, +struct ListVisitor<'a> { registry: &'a TypeRegistry, } -impl<'a, 'de> Visitor<'de> for TupleStructVisitor<'a> { - type Value = DynamicTupleStruct; +impl<'a, 'de> Visitor<'de> for ListVisitor<'a> { + type Value = DynamicList; - fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result { - formatter.write_str("reflected tuple struct value") + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("list value") } fn visit_seq(self, mut seq: V) -> Result where V: SeqAccess<'de>, { - let mut index = 0usize; - let mut tuple_struct = DynamicTupleStruct::default(); - - let get_field_info = |index: usize| -> Result<&'static 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)?, + let mut list = DynamicList::default(); + while let Some(value) = seq.next_element_seed(ReflectDeserializer { registry: self.registry, })? { - tuple_struct.insert_boxed(value); - index += 1; - if index >= self.tuple_struct_info.field_len() { - break; - } - } - - 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(), - )); + list.push_box(value); } - - Ok(tuple_struct) + Ok(list) } } -struct TupleVisitor<'a> { - tuple_info: &'static TupleInfo, +struct ArrayDeserializer<'a> { registry: &'a TypeRegistry, } -impl<'a, 'de> Visitor<'de> for TupleVisitor<'a> { - type Value = DynamicTuple; - - fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result { - formatter.write_str("reflected tuple value") - } +impl<'a, 'de> DeserializeSeed<'de> for ArrayDeserializer<'a> { + type Value = DynamicArray; - fn visit_seq(self, mut seq: V) -> Result + fn deserialize(self, deserializer: D) -> Result where - V: SeqAccess<'de>, + D: serde::Deserializer<'de>, { - visit_tuple(&mut seq, self.tuple_info, self.registry) + deserializer.deserialize_seq(ArrayVisitor { + registry: 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) -> std::fmt::Result { - formatter.write_str("reflected array value") + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("array value") } fn visit_seq(self, mut seq: V) -> Result @@ -465,71 +334,42 @@ impl<'a, 'de> Visitor<'de> for ArrayVisitor<'a> { V: SeqAccess<'de>, { let mut vec = Vec::with_capacity(seq.size_hint().unwrap_or_default()); - 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, + while let Some(value) = seq.next_element_seed(ReflectDeserializer { 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())) + Ok(DynamicArray::new(Box::from(vec))) } } -struct ListVisitor<'a> { - list_info: &'static ListInfo, +struct MapDeserializer<'a> { registry: &'a TypeRegistry, } -impl<'a, 'de> Visitor<'de> for ListVisitor<'a> { - type Value = DynamicList; - - fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result { - formatter.write_str("reflected list value") - } +impl<'a, 'de> DeserializeSeed<'de> for MapDeserializer<'a> { + type Value = DynamicMap; - fn visit_seq(self, mut seq: V) -> Result + fn deserialize(self, deserializer: D) -> Result where - V: SeqAccess<'de>, + D: serde::Deserializer<'de>, { - 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, + deserializer.deserialize_map(MapVisitor { 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) -> std::fmt::Result { - formatter.write_str("reflected map value") + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("map value") } fn visit_map(self, mut map: V) -> Result @@ -537,22 +377,10 @@ impl<'a, 'de> Visitor<'de> for MapVisitor<'a> { V: MapAccess<'de>, { let mut dynamic_map = DynamicMap::default(); - 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, + while let Some(key) = map.next_key_seed(ReflectDeserializer { registry: self.registry, })? { - let value = map.next_value_seed(TypedReflectDeserializer { - type_info: value_type_info, + let value = map.next_value_seed(ReflectDeserializer { registry: self.registry, })?; dynamic_map.insert_boxed(key, value); @@ -562,514 +390,221 @@ impl<'a, 'de> Visitor<'de> for MapVisitor<'a> { } } -struct EnumVisitor<'a> { - enum_info: &'static EnumInfo, +struct StructDeserializer<'a> { registry: &'a TypeRegistry, } -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("reflected enum value") - } +impl<'a, 'de> DeserializeSeed<'de> for StructDeserializer<'a> { + type Value = DynamicStruct; - fn visit_enum(self, data: A) -> Result + fn deserialize(self, deserializer: D) -> Result where - A: EnumAccess<'de>, + D: serde::Deserializer<'de>, { - let mut dynamic_enum = DynamicEnum::default(); - let (Ident(variant_name), variant) = data.variant().unwrap(); - let variant_info = self - .enum_info - .variant(&variant_name) - .ok_or_else(|| Error::unknown_variant(&variant_name, self.enum_info.variant_names()))?; - 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, - registry: self.registry, - }, - )? - .into(), - VariantInfo::Tuple(tuple_info) if tuple_info.field_len() == 1 => { - let type_info = get_newtype_info(tuple_info, self.registry)?; - let value = variant.newtype_variant_seed(TypedReflectDeserializer { - type_info, - 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, - registry: self.registry, - }, - )? - .into(), - }; - - dynamic_enum.set_variant(variant_name, value); - Ok(dynamic_enum) + deserializer.deserialize_map(StructVisitor { + registry: self.registry, + }) } } -struct StructVariantVisitor<'a> { - struct_info: &'static StructVariantInfo, +struct StructVisitor<'a> { registry: &'a TypeRegistry, } -impl<'a, 'de> Visitor<'de> for StructVariantVisitor<'a> { +impl<'a, 'de> Visitor<'de> for StructVisitor<'a> { type Value = DynamicStruct; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - formatter.write_str("reflected struct variant value") + formatter.write_str("struct value") } fn visit_map(self, mut map: V) -> Result where V: MapAccess<'de>, { - visit_struct(&mut map, self.struct_info, self.registry) + 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); + } + + Ok(dynamic_struct) } } -struct TupleVariantVisitor<'a> { - tuple_info: &'static TupleVariantInfo, +struct TupleStructDeserializer<'a> { registry: &'a TypeRegistry, } -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("reflected tuple variant value") - } +impl<'a, 'de> DeserializeSeed<'de> for TupleStructDeserializer<'a> { + type Value = DynamicTupleStruct; - fn visit_seq(self, mut seq: V) -> Result + fn deserialize(self, deserializer: D) -> Result where - V: SeqAccess<'de>, + D: serde::Deserializer<'de>, { - visit_tuple(&mut seq, self.tuple_info, self.registry) + deserializer.deserialize_seq(TupleStructVisitor { + registry: self.registry, + }) } } -struct OptionVisitor<'a> { - enum_info: &'static EnumInfo, +struct TupleStructVisitor<'a> { registry: &'a TypeRegistry, } -impl<'a, 'de> Visitor<'de> for OptionVisitor<'a> { - type Value = DynamicEnum; +impl<'a, 'de> Visitor<'de> for TupleStructVisitor<'a> { + type Value = DynamicTupleStruct; - fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { - formatter.write_str("reflected option value of type ")?; - formatter.write_str(self.enum_info.type_name()) + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("tuple struct value") } - fn visit_some(self, deserializer: D) -> Result + fn visit_seq(self, mut seq: V) -> Result where - D: serde::Deserializer<'de>, + V: SeqAccess<'de>, { - let variant_info = self.enum_info.variant("Some").unwrap(); - match variant_info { - VariantInfo::Tuple(tuple_info) if tuple_info.field_len() == 1 => { - let type_info = get_newtype_info(tuple_info, self.registry)?; - let de = TypedReflectDeserializer { - type_info, - 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() - ))), + let mut tuple_struct = DynamicTupleStruct::default(); + while let Some(value) = seq.next_element_seed(ReflectDeserializer { + registry: self.registry, + })? { + tuple_struct.insert_boxed(value); } - } - - fn visit_none(self) -> Result - where - E: Error, - { - let mut option = DynamicEnum::default(); - option.set_variant("None", ()); - Ok(option) + Ok(tuple_struct) } } -fn visit_struct<'de, T, V>( - map: &mut V, - info: &'static T, - 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(|| Error::unknown_field(&key, info.get_field_names()))?; - 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) +struct TupleDeserializer<'a> { + registry: &'a TypeRegistry, } -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::invalid_length(index, &info.get_field_len().to_string().as_str()) - })?; - 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; - } - } - - let len = info.get_field_len(); +impl<'a, 'de> DeserializeSeed<'de> for TupleDeserializer<'a> { + type Value = DynamicTuple; - if tuple.field_len() != len { - return Err(Error::invalid_length( - tuple.field_len(), - &len.to_string().as_str(), - )); + fn deserialize(self, deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + deserializer.deserialize_seq(TupleVisitor { + registry: self.registry, + }) } - - Ok(tuple) -} - -fn get_newtype_info( - tuple_info: &'static TupleVariantInfo, - registry: &TypeRegistry, -) -> Result<&'static TypeInfo, E> { - let field = tuple_info.field_at(0).unwrap(); - registry.get_type_info(field.type_id()).ok_or_else(|| { - Error::custom(format_args!( - "no registration found for type {}", - field.type_name() - )) - }) } -fn get_type_info( - type_id: TypeId, - type_name: &str, - registry: &TypeRegistry, -) -> Result<&'static 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()) +struct TupleVisitor<'a> { + registry: &'a TypeRegistry, } -#[cfg(test)] -mod tests { - use std::f32::consts::PI; - - 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, - } +impl<'a, 'de> Visitor<'de> for TupleVisitor<'a> { + type Value = DynamicTuple; - #[derive(Reflect, FromReflect, Debug, PartialEq)] - struct SomeStruct { - foo: i64, + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("tuple value") } - #[derive(Reflect, FromReflect, Debug, PartialEq)] - struct SomeTupleStruct(String); - - #[derive(Reflect, FromReflect, Debug, PartialEq, Deserialize)] - struct SomeDeserializableStruct { - foo: i64, + 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); + } + Ok(tuple) } +} - /// 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, - } +struct EnumDeserializer<'a> { + registry: &'a TypeRegistry, +} - #[derive(Reflect, FromReflect, Debug, PartialEq)] - enum SomeEnum { - Unit, - NewType(usize), - Tuple(f32, f32), - Struct { foo: String }, - } +impl<'a, 'de> DeserializeSeed<'de> for EnumDeserializer<'a> { + type Value = DynamicEnum; - 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 + fn deserialize(self, deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + deserializer.deserialize_map(EnumVisitor { + registry: self.registry, + }) } +} - #[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 }, - }, - }; +struct EnumVisitor<'a> { + registry: &'a TypeRegistry, +} - 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 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 = ::from_reflect(dynamic_output.as_ref()).unwrap(); - assert_eq!(expected, output); - } +impl<'a, 'de> Visitor<'de> for EnumVisitor<'a> { + type Value = DynamicEnum; - #[test] - fn should_deserialize_value() { - let input = r#"{ - "f32": 1.23, - }"#; - - 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); + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("enum value") } - #[test] - fn should_deserialized_typed() { - #[derive(Reflect, FromReflect, Debug, PartialEq)] - struct Foo { - bar: i32, + 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)); + } } - let expected = Foo { bar: 123 }; + let variant_name = map.next_value::()?; - 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); - } + let mut dynamic_enum = DynamicEnum::default(); - #[test] - fn should_deserialize_option() { - #[derive(Reflect, FromReflect, Debug, PartialEq)] - struct OptionTest { - none: Option<()>, - simple: Option, - complex: Option, + 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 expected = OptionTest { - none: None, - simple: Some(String::from("Hello world!")), - complex: Some(SomeStruct { foo: 123 }), - }; + Ok(dynamic_enum) + } +} - let mut registry = get_registry(); - registry.register::(); - registry.register::>(); +#[cfg(test)] +mod tests { + use super::ReflectDeserializer; + use crate as bevy_reflect; + use crate::prelude::*; + use crate::{DynamicEnum, TypeRegistry}; + use ::serde::de::DeserializeSeed; - // === Normal === // - let input = r#"{ - "bevy_reflect::serde::de::tests::should_deserialize_option::OptionTest": ( - none: None, - simple: Some("Hello world!"), - complex: Some(( - foo: 123, - )), - ), - }"#; - - 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 = ::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::should_deserialize_option::OptionTest": ( - none: None, - simple: "Hello world!", - complex: ( - foo: 123, - ), - ), - }"#; - - 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 = ::from_reflect(dynamic_output.as_ref()).unwrap(); - assert_eq!( - expected, output, - "failed to deserialize Options with implicit Some" - ); + fn get_registry() -> TypeRegistry { + let mut registry = TypeRegistry::default(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::<(f32, f32)>(); + registry } #[test] @@ -1087,9 +622,12 @@ mod tests { // === Unit Variant === // let input = r#"{ - "bevy_reflect::serde::de::tests::enum_should_deserialize::MyEnum": Unit, + "type": "bevy_reflect::serde::de::tests::enum_should_deserialize::MyEnum", + "enum": { + "variant": "Unit", + }, }"#; - let reflect_deserializer = UntypedReflectDeserializer::new(®istry); + let reflect_deserializer = ReflectDeserializer::new(®istry); let mut deserializer = ron::de::Deserializer::from_str(input).unwrap(); let output = reflect_deserializer.deserialize(&mut deserializer).unwrap(); @@ -1098,9 +636,18 @@ mod tests { // === NewType Variant === // let input = r#"{ - "bevy_reflect::serde::de::tests::enum_should_deserialize::MyEnum": NewType(123), + "type": "bevy_reflect::serde::de::tests::enum_should_deserialize::MyEnum", + "enum": { + "variant": "NewType", + "tuple": [ + { + "type": "usize", + "value": 123, + }, + ], + }, }"#; - let reflect_deserializer = UntypedReflectDeserializer::new(®istry); + let reflect_deserializer = ReflectDeserializer::new(®istry); let mut deserializer = ron::de::Deserializer::from_str(input).unwrap(); let output = reflect_deserializer.deserialize(&mut deserializer).unwrap(); @@ -1109,9 +656,22 @@ mod tests { // === Tuple Variant === // let input = r#"{ - "bevy_reflect::serde::de::tests::enum_should_deserialize::MyEnum": Tuple(1.23, 3.21), + "type": "bevy_reflect::serde::de::tests::enum_should_deserialize::MyEnum", + "enum": { + "variant": "Tuple", + "tuple": [ + { + "type": "f32", + "value": 1.23, + }, + { + "type": "f32", + "value": 3.21, + }, + ], + }, }"#; - let reflect_deserializer = UntypedReflectDeserializer::new(®istry); + let reflect_deserializer = ReflectDeserializer::new(®istry); let mut deserializer = ron::de::Deserializer::from_str(input).unwrap(); let output = reflect_deserializer.deserialize(&mut deserializer).unwrap(); @@ -1120,11 +680,18 @@ mod tests { // === Struct Variant === // let input = r#"{ - "bevy_reflect::serde::de::tests::enum_should_deserialize::MyEnum": Struct( - value: "I <3 Enums", - ), + "type": "bevy_reflect::serde::de::tests::enum_should_deserialize::MyEnum", + "enum": { + "variant": "Struct", + "struct": { + "value": { + "type": "alloc::string::String", + "value": "I <3 Enums", + }, + }, + }, }"#; - let reflect_deserializer = UntypedReflectDeserializer::new(®istry); + let reflect_deserializer = ReflectDeserializer::new(®istry); let mut deserializer = ron::de::Deserializer::from_str(input).unwrap(); let 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 21612b6c055536..7c7c18f4ea954e 100644 --- a/crates/bevy_reflect/src/serde/mod.rs +++ b/crates/bevy_reflect/src/serde/mod.rs @@ -3,3 +3,16 @@ 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 2ed65718abb9ca..0dd239d6305a72 100644 --- a/crates/bevy_reflect/src/serde/ser.rs +++ b/crates/bevy_reflect/src/serde/ser.rs @@ -1,14 +1,11 @@ use crate::{ - Array, Enum, List, Map, Reflect, ReflectRef, ReflectSerialize, Struct, Tuple, TupleStruct, - TypeInfo, TypeRegistry, VariantInfo, VariantType, -}; -use serde::ser::{ - Error, SerializeStruct, SerializeStructVariant, SerializeTuple, SerializeTupleStruct, - SerializeTupleVariant, + serde::type_fields, Array, Enum, List, Map, Reflect, ReflectRef, ReflectSerialize, Struct, + Tuple, TupleStruct, TypeRegistry, VariantType, }; +use serde::ser::Error; use serde::{ ser::{SerializeMap, SerializeSeq}, - Serialize, + Serialize, Serializer, }; pub enum Serializable<'a> { @@ -41,34 +38,6 @@ fn get_serializable<'a, E: serde::ser::Error>( Ok(reflect_serialize.get_serializable(reflect_value)) } -/// Get the underlying [`TypeInfo`] of a given type. -/// -/// If the given type is a [`TypeInfo::Dynamic`] then we need to try and look -/// up the actual type in the registry. -fn get_type_info( - type_info: &'static TypeInfo, - type_name: &str, - registry: &TypeRegistry, -) -> Result<&'static TypeInfo, E> { - match type_info { - TypeInfo::Dynamic(..) => match registry.get_with_name(type_name) { - Some(registration) => Ok(registration.type_info()), - None => Err(Error::custom(format_args!( - "no registration found for dynamic type with name {}", - type_name - ))), - }, - info => Ok(info), - } -} - -/// 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, @@ -85,39 +54,6 @@ 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, @@ -154,7 +90,11 @@ impl<'a> Serialize for TypedReflectSerializer<'a> { registry: self.registry, } .serialize(serializer), - ReflectRef::Value(_) => Err(serializable.err().unwrap()), + ReflectRef::Value(value) => ReflectValueSerializer { + registry: self.registry, + value, + } + .serialize(serializer), } } } @@ -169,9 +109,13 @@ impl<'a> Serialize for ReflectValueSerializer<'a> { where S: serde::Serializer, { - get_serializable::(self.value, self.registry)? - .borrow() - .serialize(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() } } @@ -185,27 +129,34 @@ impl<'a> Serialize for StructSerializer<'a> { where S: serde::Serializer, { - let type_info = get_type_info( - self.struct_value.get_type_info(), - self.struct_value.type_name(), - self.registry, + 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() + } +} - 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 - ))); - } - }; +pub struct StructValueSerializer<'a> { + pub struct_value: &'a dyn Struct, + pub registry: &'a TypeRegistry, +} - let mut state = - serializer.serialize_struct(struct_info.name(), self.struct_value.field_len())?; +impl<'a> Serialize for StructValueSerializer<'a> { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_map(Some(self.struct_value.field_len()))?; for (index, value) in self.struct_value.iter_fields().enumerate() { - let key = struct_info.field_at(index).unwrap().name(); - state.serialize_field(key, &TypedReflectSerializer::new(value, self.registry))?; + let key = self.struct_value.name_at(index).unwrap(); + state.serialize_entry(key, &ReflectSerializer::new(value, self.registry))?; } state.end() } @@ -221,25 +172,33 @@ impl<'a> Serialize for TupleStructSerializer<'a> { where S: serde::Serializer, { - let type_info = get_type_info( - self.tuple_struct.get_type_info(), - self.tuple_struct.type_name(), - self.registry, + 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() + } +} - 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 mut state = serializer - .serialize_tuple_struct(tuple_struct_info.name(), self.tuple_struct.field_len())?; +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()))?; for value in self.tuple_struct.iter_fields() { - state.serialize_field(&TypedReflectSerializer::new(value, self.registry))?; + state.serialize_element(&ReflectSerializer::new(value, self.registry))?; } state.end() } @@ -255,114 +214,104 @@ impl<'a> Serialize for EnumSerializer<'a> { where S: serde::Serializer, { - let type_info = get_type_info( - self.enum_value.get_type_info(), - self.enum_value.type_name(), - self.registry, + let mut state = serializer.serialize_map(Some(2))?; + + state.serialize_entry(type_fields::TYPE, self.enum_value.type_name())?; + state.serialize_entry( + type_fields::ENUM, + &EnumValueSerializer { + enum_value: self.enum_value, + registry: self.registry, + }, )?; + state.end() + } +} - 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 - ))); - } - }; +pub struct EnumValueSerializer<'a> { + pub enum_value: &'a dyn Enum, + pub registry: &'a TypeRegistry, +} - let enum_name = enum_info.name(); - let variant_info = enum_info - .variant(self.enum_value.variant_name()) - .ok_or_else(|| { - Error::custom(format_args!( - "variant `{}` does not exist", - self.enum_value.variant_name() - )) - })?; - let variant_index = enum_info - .index_of(self.enum_value.variant_name()) - .ok_or_else(|| { - Error::custom(format_args!( - "variant `{}` does not exist", - self.enum_value.variant_name() - )) - })? as u32; - let variant_name = variant_info.name(); +impl<'a> Serialize for EnumValueSerializer<'a> { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { let variant_type = self.enum_value.variant_type(); - let field_len = self.enum_value.field_len(); + let variant_name = self.enum_value.variant_name(); - match variant_type { - VariantType::Unit => { - if self - .enum_value - .type_name() - .starts_with("core::option::Option") - { - serializer.serialize_none() - } else { - serializer.serialize_unit_variant(enum_name, variant_index, 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 => { - 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 self - .enum_value - .type_name() - .starts_with("core::option::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), - ) - } + state.serialize_key(type_fields::STRUCT)?; + state.serialize_value(&StructVariantSerializer { + enum_value: self.enum_value, + registry: 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() + state.serialize_key(type_fields::TUPLE)?; + state.serialize_value(&TupleVariantSerializer { + enum_value: self.enum_value, + registry: self.registry, + })?; } + _ => {} + } + + state.end() + } +} + +pub struct TupleVariantSerializer<'a> { + pub enum_value: &'a dyn Enum, + pub registry: &'a TypeRegistry, +} + +impl<'a> Serialize for TupleVariantSerializer<'a> { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let field_len = self.enum_value.field_len(); + let mut state = serializer.serialize_seq(Some(field_len))?; + for field in self.enum_value.iter_fields() { + state.serialize_element(&ReflectSerializer::new(field.value(), self.registry))?; + } + state.end() + } +} + +pub struct StructVariantSerializer<'a> { + pub enum_value: &'a dyn Enum, + pub registry: &'a TypeRegistry, +} + +impl<'a> Serialize for StructVariantSerializer<'a> { + fn serialize(&self, serializer: S) -> Result + 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))?; } + state.end() } } @@ -376,9 +325,33 @@ impl<'a> Serialize for TupleSerializer<'a> { where S: serde::Serializer, { - let mut state = serializer.serialize_tuple(self.tuple.field_len())?; + 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()))?; for value in self.tuple.iter_fields() { - state.serialize_element(&TypedReflectSerializer::new(value, self.registry))?; + state.serialize_element(&ReflectSerializer::new(value, self.registry))?; } state.end() } @@ -390,6 +363,30 @@ 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, @@ -397,8 +394,8 @@ impl<'a> Serialize for MapSerializer<'a> { 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), + &ReflectSerializer::new(key, self.registry), + &ReflectSerializer::new(value, self.registry), )?; } state.end() @@ -411,13 +408,36 @@ 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(&TypedReflectSerializer::new(value, self.registry))?; + state.serialize_element(&ReflectSerializer::new(value, self.registry))?; } state.end() } @@ -433,9 +453,32 @@ impl<'a> Serialize for ArraySerializer<'a> { where S: serde::Serializer, { - let mut state = serializer.serialize_tuple(self.array.len())?; + 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()))?; for value in self.array.iter() { - state.serialize_element(&TypedReflectSerializer::new(value, self.registry))?; + state.serialize_element(&ReflectSerializer::new(value, self.registry))?; } state.end() } @@ -443,214 +486,21 @@ impl<'a> Serialize for ArraySerializer<'a> { #[cfg(test)] mod tests { + use super::ReflectSerializer; use crate as bevy_reflect; - use crate::serde::ReflectSerializer; - use crate::{FromReflect, Reflect, ReflectSerialize, TypeRegistry}; - use bevy_utils::HashMap; - use ron::extensions::Extensions; + use crate::prelude::*; + use crate::TypeRegistry; 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_type_data::(); + registry.register::(); + registry.register::(); registry.register::(); - registry.register::>(); - registry.register_type_data::, ReflectSerialize>(); + registry.register::<(f32, f32)>(); 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 should_serialize_option() { - #[derive(Reflect, FromReflect, 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")) - .decimal_floats(true) - .indentor(String::from(" ")); - - let output = ron::ser::to_string_pretty(&serializer, config).unwrap(); - let expected = r#"{ - "bevy_reflect::serde::ser::tests::should_serialize_option::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")) - .decimal_floats(true) - .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::should_serialize_option::OptionTest": ( - none: None, - simple: "Hello world!", - complex: ( - foo: 123, - ), - ), -}"#; - - assert_eq!(expected, output); - } - #[test] fn enum_should_serialize() { #[derive(Reflect)] @@ -671,7 +521,10 @@ mod tests { 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::enum_should_serialize::MyEnum": Unit, + "type": "bevy_reflect::serde::ser::tests::enum_should_serialize::MyEnum", + "enum": { + "variant": "Unit", + }, }"#; assert_eq!(expected, output); @@ -680,7 +533,16 @@ mod tests { 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::enum_should_serialize::MyEnum": NewType(123), + "type": "bevy_reflect::serde::ser::tests::enum_should_serialize::MyEnum", + "enum": { + "variant": "NewType", + "tuple": [ + { + "type": "usize", + "value": 123, + }, + ], + }, }"#; assert_eq!(expected, output); @@ -689,7 +551,20 @@ mod tests { 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::enum_should_serialize::MyEnum": Tuple(1.23, 3.21), + "type": "bevy_reflect::serde::ser::tests::enum_should_serialize::MyEnum", + "enum": { + "variant": "Tuple", + "tuple": [ + { + "type": "f32", + "value": 1.23, + }, + { + "type": "f32", + "value": 3.21, + }, + ], + }, }"#; assert_eq!(expected, output); @@ -700,10 +575,17 @@ mod tests { let serializer = ReflectSerializer::new(&value, ®istry); let output = ron::ser::to_string_pretty(&serializer, config).unwrap(); let expected = r#"{ - "bevy_reflect::serde::ser::tests::enum_should_serialize::MyEnum": Struct( - value: "I <3 Enums", - ), + "type": "bevy_reflect::serde::ser::tests::enum_should_serialize::MyEnum", + "enum": { + "variant": "Struct", + "struct": { + "value": { + "type": "alloc::string::String", + "value": "I <3 Enums", + }, + }, + }, }"#; - assert_eq!(expected, output); + assert_eq!(expected, output.replace('\r', "")); } } diff --git a/crates/bevy_reflect/src/struct_trait.rs b/crates/bevy_reflect/src/struct_trait.rs index 72b87b99ab5aa8..4f0b7819f258de 100644 --- a/crates/bevy_reflect/src/struct_trait.rs +++ b/crates/bevy_reflect/src/struct_trait.rs @@ -69,12 +69,10 @@ pub trait Struct: Reflect { /// A container for compile-time struct info. #[derive(Clone, Debug)] pub struct StructInfo { - name: &'static str, type_name: &'static str, type_id: TypeId, fields: Box<[NamedField]>, - field_names: Box<[&'static str]>, - field_indices: HashMap<&'static str, usize>, + field_indices: HashMap, usize>, } impl StructInfo { @@ -82,22 +80,21 @@ impl StructInfo { /// /// # Arguments /// - /// * `name`: The name of this struct (_without_ generics or lifetimes) /// * `fields`: The fields of this struct in the order they are defined /// - pub fn new(name: &'static str, fields: &[NamedField]) -> Self { + pub fn new(fields: &[NamedField]) -> Self { let field_indices = fields .iter() .enumerate() - .map(|(index, field)| (field.name(), index)) + .map(|(index, field)| { + let name = field.name().clone(); + (name, index) + }) .collect::>(); - let field_names = fields.iter().map(|field| field.name()).collect::>(); Self { - name, type_name: std::any::type_name::(), type_id: TypeId::of::(), - field_names: field_names.into_boxed_slice(), fields: fields.to_vec().into_boxed_slice(), field_indices, } @@ -110,11 +107,6 @@ impl StructInfo { .map(|index| &self.fields[*index]) } - /// A slice containing the names of all fields in order. - pub fn field_names(&self) -> &[&'static str] { - &self.field_names - } - /// Get the field at the given index. pub fn field_at(&self, index: usize) -> Option<&NamedField> { self.fields.get(index) @@ -135,15 +127,6 @@ impl StructInfo { self.fields.len() } - /// The name of the struct. - /// - /// This does _not_ include any generics or lifetimes. - /// - /// For example, `foo::bar::Baz<'a, T>` would simply be `Baz`. - pub fn name(&self) -> &'static str { - self.name - } - /// The [type name] of the struct. /// /// [type name]: std::any::type_name diff --git a/crates/bevy_reflect/src/tuple_struct.rs b/crates/bevy_reflect/src/tuple_struct.rs index e7bb89cebb5a8a..507b6b4bfd1175 100644 --- a/crates/bevy_reflect/src/tuple_struct.rs +++ b/crates/bevy_reflect/src/tuple_struct.rs @@ -49,7 +49,6 @@ pub trait TupleStruct: Reflect { /// A container for compile-time tuple struct info. #[derive(Clone, Debug)] pub struct TupleStructInfo { - name: &'static str, type_name: &'static str, type_id: TypeId, fields: Box<[UnnamedField]>, @@ -60,12 +59,10 @@ impl TupleStructInfo { /// /// # Arguments /// - /// * `name`: The name of this struct (_without_ generics or lifetimes) /// * `fields`: The fields of this struct in the order they are defined /// - pub fn new(name: &'static str, fields: &[UnnamedField]) -> Self { + pub fn new(fields: &[UnnamedField]) -> Self { Self { - name, type_name: std::any::type_name::(), type_id: TypeId::of::(), fields: fields.to_vec().into_boxed_slice(), @@ -87,15 +84,6 @@ impl TupleStructInfo { self.fields.len() } - /// The name of the struct. - /// - /// This does _not_ include any generics or lifetimes. - /// - /// For example, `foo::bar::Baz<'a, T>` would simply be `Baz`. - pub fn name(&self) -> &'static str { - self.name - } - /// The [type name] of the tuple struct. /// /// [type name]: std::any::type_name diff --git a/crates/bevy_reflect/src/type_info.rs b/crates/bevy_reflect/src/type_info.rs index a954082f9b9c6d..afbe037b7243d8 100644 --- a/crates/bevy_reflect/src/type_info.rs +++ b/crates/bevy_reflect/src/type_info.rs @@ -40,7 +40,7 @@ use std::any::{Any, TypeId}; /// NamedField::new::("foo"), /// NamedField::new::<(f32, f32), _>("bar"), /// ]; -/// let info = StructInfo::new::("MyStruct", &fields); +/// let info = StructInfo::new::(&fields); /// TypeInfo::Struct(info) /// }) /// } diff --git a/crates/bevy_reflect/src/utility.rs b/crates/bevy_reflect/src/utility.rs index c11d2a08cf7b50..3e38c6dc359326 100644 --- a/crates/bevy_reflect/src/utility.rs +++ b/crates/bevy_reflect/src/utility.rs @@ -28,7 +28,7 @@ use std::any::{Any, TypeId}; /// static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new(); /// CELL.get_or_set(|| { /// let fields = [NamedField::new::("bar")]; -/// let info = StructInfo::new::("Foo", &fields); +/// let info = StructInfo::new::(&fields); /// TypeInfo::Struct(info) /// }) /// } @@ -89,7 +89,7 @@ impl NonGenericTypeInfoCell { /// static CELL: GenericTypeInfoCell = GenericTypeInfoCell::new(); /// CELL.get_or_insert::(|| { /// let fields = [UnnamedField::new::(0)]; -/// let info = TupleStructInfo::new::("Foo", &fields); +/// let info = TupleStructInfo::new::(&fields); /// TypeInfo::TupleStruct(info) /// }) /// } diff --git a/crates/bevy_scene/src/serde.rs b/crates/bevy_scene/src/serde.rs index 8a3e5383af1701..e55a5fd4b592b2 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::{ReflectSerializer, UntypedReflectDeserializer}, + serde::{ReflectDeserializer, ReflectSerializer}, Reflect, TypeRegistry, TypeRegistryArc, }; use serde::{ @@ -242,9 +242,7 @@ 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(UntypedReflectDeserializer::new(self.registry))? - { + while let Some(entity) = seq.next_element_seed(ReflectDeserializer::new(self.registry))? { dynamic_properties.push(entity); } diff --git a/examples/reflection/reflection.rs b/examples/reflection/reflection.rs index 87bed8664e225d..8197299cb1732c 100644 --- a/examples/reflection/reflection.rs +++ b/examples/reflection/reflection.rs @@ -81,7 +81,7 @@ fn setup(type_registry: Res) { info!("{}\n", ron_string); // Dynamic properties can be deserialized - let reflect_deserializer = UntypedReflectDeserializer::new(&type_registry); + let reflect_deserializer = ReflectDeserializer::new(&type_registry); let mut deserializer = ron::de::Deserializer::from_str(&ron_string).unwrap(); let reflect_value = reflect_deserializer.deserialize(&mut deserializer).unwrap();