diff --git a/crates/bevy_reflect/src/serde/de.rs b/crates/bevy_reflect/src/serde/de.rs deleted file mode 100644 index 5563d9192f..0000000000 --- a/crates/bevy_reflect/src/serde/de.rs +++ /dev/null @@ -1,1712 +0,0 @@ -use crate::serde::SerializationData; -use crate::{ - ArrayInfo, DynamicArray, DynamicEnum, DynamicList, DynamicMap, DynamicSet, DynamicStruct, - DynamicTuple, DynamicTupleStruct, DynamicVariant, EnumInfo, ListInfo, Map, MapInfo, NamedField, - PartialReflect, Reflect, ReflectDeserialize, Set, SetInfo, StructInfo, StructVariantInfo, - TupleInfo, TupleStructInfo, TupleVariantInfo, TypeInfo, TypeRegistration, TypeRegistry, - VariantInfo, -}; -use erased_serde::Deserializer; -use serde::de::{ - DeserializeSeed, EnumAccess, Error, IgnoredAny, MapAccess, SeqAccess, VariantAccess, Visitor, -}; -use serde::Deserialize; -use std::any::TypeId; -use std::fmt; -use std::fmt::{Debug, Display, Formatter}; -use std::slice::Iter; - -pub trait DeserializeValue { - fn deserialize( - deserializer: &mut dyn Deserializer, - type_registry: &TypeRegistry, - ) -> Result, erased_serde::Error>; -} - -trait StructLikeInfo { - fn get_field(&self, name: &str) -> Option<&NamedField>; - fn field_at(&self, index: usize) -> Option<&NamedField>; - fn get_field_len(&self) -> usize; - fn iter_fields(&self) -> Iter<'_, NamedField>; -} - -trait TupleLikeInfo { - fn get_field_len(&self) -> usize; -} - -trait Container { - fn get_field_registration<'a, E: Error>( - &self, - index: usize, - registry: &'a TypeRegistry, - ) -> Result<&'a TypeRegistration, E>; -} - -impl StructLikeInfo for StructInfo { - fn get_field(&self, name: &str) -> Option<&NamedField> { - self.field(name) - } - - fn field_at(&self, index: usize) -> Option<&NamedField> { - self.field_at(index) - } - - fn get_field_len(&self) -> usize { - self.field_len() - } - - fn iter_fields(&self) -> Iter<'_, NamedField> { - self.iter() - } -} - -impl Container for StructInfo { - fn get_field_registration<'a, E: Error>( - &self, - index: usize, - registry: &'a TypeRegistry, - ) -> Result<&'a TypeRegistration, E> { - let field = self.field_at(index).ok_or_else(|| { - Error::custom(format_args!( - "no field at index {} on struct {}", - index, - self.type_path(), - )) - })?; - get_registration(field.type_id(), field.type_path(), registry) - } -} - -impl StructLikeInfo for StructVariantInfo { - fn get_field(&self, name: &str) -> Option<&NamedField> { - self.field(name) - } - - fn field_at(&self, index: usize) -> Option<&NamedField> { - self.field_at(index) - } - - fn get_field_len(&self) -> usize { - self.field_len() - } - - fn iter_fields(&self) -> Iter<'_, NamedField> { - self.iter() - } -} - -impl Container for StructVariantInfo { - fn get_field_registration<'a, E: Error>( - &self, - index: usize, - registry: &'a TypeRegistry, - ) -> Result<&'a TypeRegistration, E> { - let field = self.field_at(index).ok_or_else(|| { - Error::custom(format_args!( - "no field at index {} on variant {}", - index, - self.name(), - )) - })?; - get_registration(field.type_id(), field.type_path(), registry) - } -} - -impl TupleLikeInfo for TupleInfo { - fn get_field_len(&self) -> usize { - self.field_len() - } -} - -impl Container for TupleInfo { - fn get_field_registration<'a, E: Error>( - &self, - index: usize, - registry: &'a TypeRegistry, - ) -> Result<&'a TypeRegistration, E> { - let field = self.field_at(index).ok_or_else(|| { - Error::custom(format_args!( - "no field at index {} on tuple {}", - index, - self.type_path(), - )) - })?; - get_registration(field.type_id(), field.type_path(), registry) - } -} - -impl TupleLikeInfo for TupleStructInfo { - fn get_field_len(&self) -> usize { - self.field_len() - } -} - -impl Container for TupleStructInfo { - fn get_field_registration<'a, E: Error>( - &self, - index: usize, - registry: &'a TypeRegistry, - ) -> Result<&'a TypeRegistration, E> { - let field = self.field_at(index).ok_or_else(|| { - Error::custom(format_args!( - "no field at index {} on tuple struct {}", - index, - self.type_path(), - )) - })?; - get_registration(field.type_id(), field.type_path(), registry) - } -} - -impl TupleLikeInfo for TupleVariantInfo { - fn get_field_len(&self) -> usize { - self.field_len() - } -} - -impl Container for TupleVariantInfo { - fn get_field_registration<'a, E: Error>( - &self, - index: usize, - registry: &'a TypeRegistry, - ) -> Result<&'a TypeRegistration, E> { - let field = self.field_at(index).ok_or_else(|| { - Error::custom(format_args!( - "no field at index {} on tuple variant {}", - index, - self.name(), - )) - })?; - get_registration(field.type_id(), field.type_path(), registry) - } -} - -/// A debug struct used for error messages that displays a list of expected values. -/// -/// # Example -/// -/// ```ignore (Can't import private struct from doctest) -/// let expected = vec!["foo", "bar", "baz"]; -/// assert_eq!("`foo`, `bar`, `baz`", format!("{}", ExpectedValues(expected))); -/// ``` -struct ExpectedValues(Vec); - -impl Debug for ExpectedValues { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - let len = self.0.len(); - for (index, item) in self.0.iter().enumerate() { - write!(f, "`{item}`")?; - if index < len - 1 { - write!(f, ", ")?; - } - } - Ok(()) - } -} - -/// Represents a simple reflected identifier. -#[derive(Debug, Clone, Eq, PartialEq)] -struct Ident(String); - -impl<'de> Deserialize<'de> for Ident { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - struct IdentVisitor; - - impl<'de> Visitor<'de> for IdentVisitor { - type Value = Ident; - - fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { - formatter.write_str("identifier") - } - - fn visit_str(self, value: &str) -> Result - where - E: Error, - { - Ok(Ident(value.to_string())) - } - - fn visit_string(self, value: String) -> Result - where - E: Error, - { - Ok(Ident(value)) - } - } - - deserializer.deserialize_identifier(IdentVisitor) - } -} - -/// A deserializer for type registrations. -/// -/// This will return a [`&TypeRegistration`] corresponding to the given type. -/// This deserializer expects a string containing the _full_ [type path] of the -/// type to find the `TypeRegistration` of. -/// -/// [`&TypeRegistration`]: TypeRegistration -/// [type path]: crate::TypePath::type_path -pub struct TypeRegistrationDeserializer<'a> { - registry: &'a TypeRegistry, -} - -impl<'a> TypeRegistrationDeserializer<'a> { - pub fn new(registry: &'a TypeRegistry) -> Self { - Self { registry } - } -} - -impl<'a, 'de> DeserializeSeed<'de> for TypeRegistrationDeserializer<'a> { - type Value = &'a TypeRegistration; - - fn deserialize(self, deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - struct TypeRegistrationVisitor<'a>(&'a TypeRegistry); - - impl<'de, 'a> Visitor<'de> for TypeRegistrationVisitor<'a> { - type Value = &'a TypeRegistration; - - fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { - formatter.write_str("string containing `type` entry for the reflected value") - } - - fn visit_str(self, type_path: &str) -> Result - where - E: Error, - { - self.0.get_with_type_path(type_path).ok_or_else(|| { - Error::custom(format_args!("No registration found for `{type_path}`")) - }) - } - } - - deserializer.deserialize_str(TypeRegistrationVisitor(self.registry)) - } -} - -/// A general purpose deserializer for reflected types. -/// -/// This is the deserializer counterpart to [`ReflectSerializer`]. -/// -/// See [`TypedReflectDeserializer`] for a deserializer that expects a known type. -/// -/// # Input -/// -/// This deserializer expects a map with a single entry, -/// where the key is the _full_ [type path] of the reflected type -/// and the value is the serialized data. -/// -/// # Output -/// -/// This deserializer will return a [`Box`] containing the deserialized data. -/// -/// For value types (i.e. [`ReflectKind::Value`]) or types that register [`ReflectDeserialize`] type data, -/// this `Box` will contain the expected type. -/// For example, deserializing an `i32` will return a `Box` (as a `Box`). -/// -/// Otherwise, this `Box` will contain the dynamic equivalent. -/// For example, a deserialized struct might return a [`Box`] -/// and a deserialized `Vec` might return a [`Box`]. -/// -/// This means that if the actual type is needed, these dynamic representations will need to -/// be converted to the concrete type using [`FromReflect`] or [`ReflectFromReflect`]. -/// -/// # Example -/// -/// ``` -/// # use serde::de::DeserializeSeed; -/// # use bevy_reflect::prelude::*; -/// # use bevy_reflect::{DynamicStruct, TypeRegistry, serde::ReflectDeserializer}; -/// #[derive(Reflect, PartialEq, Debug)] -/// #[type_path = "my_crate"] -/// struct MyStruct { -/// value: i32 -/// } -/// -/// let mut registry = TypeRegistry::default(); -/// registry.register::(); -/// -/// let input = r#"{ -/// "my_crate::MyStruct": ( -/// value: 123 -/// ) -/// }"#; -/// -/// let mut deserializer = ron::Deserializer::from_str(input).unwrap(); -/// let reflect_deserializer = ReflectDeserializer::new(®istry); -/// -/// let output: Box = reflect_deserializer.deserialize(&mut deserializer).unwrap(); -/// -/// // Since `MyStruct` is not a value type and does not register `ReflectDeserialize`, -/// // we know that its deserialized value will be a `DynamicStruct`, -/// // although it will represent `MyStruct`. -/// assert!(output.as_partial_reflect().represents::()); -/// -/// // We can convert back to `MyStruct` using `FromReflect`. -/// let value: MyStruct = ::from_reflect(output.as_partial_reflect()).unwrap(); -/// assert_eq!(value, MyStruct { value: 123 }); -/// -/// // We can also do this dynamically with `ReflectFromReflect`. -/// let type_id = output.get_represented_type_info().unwrap().type_id(); -/// let reflect_from_reflect = registry.get_type_data::(type_id).unwrap(); -/// let value: Box = reflect_from_reflect.from_reflect(output.as_partial_reflect()).unwrap(); -/// assert!(value.is::()); -/// assert_eq!(value.take::().unwrap(), MyStruct { value: 123 }); -/// ``` -/// -/// [`ReflectSerializer`]: crate::serde::ReflectSerializer -/// [type path]: crate::TypePath::type_path -/// [`Box`]: crate::Reflect -/// [`ReflectKind::Value`]: crate::ReflectKind::Value -/// [`ReflectDeserialize`]: crate::ReflectDeserialize -/// [`Box`]: crate::DynamicStruct -/// [`Box`]: crate::DynamicList -/// [`FromReflect`]: crate::FromReflect -/// [`ReflectFromReflect`]: crate::ReflectFromReflect -pub struct ReflectDeserializer<'a> { - registry: &'a TypeRegistry, -} - -impl<'a> ReflectDeserializer<'a> { - pub fn new(registry: &'a TypeRegistry) -> Self { - Self { registry } - } -} - -impl<'a, 'de> DeserializeSeed<'de> for ReflectDeserializer<'a> { - type Value = Box; - - fn deserialize(self, deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - struct UntypedReflectDeserializerVisitor<'a> { - registry: &'a TypeRegistry, - } - - impl<'a, 'de> Visitor<'de> for UntypedReflectDeserializerVisitor<'a> { - type Value = Box; - - fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { - formatter - .write_str("map containing `type` and `value` entries for the reflected value") - } - - fn visit_map(self, mut map: A) -> Result - where - A: MapAccess<'de>, - { - let registration = map - .next_key_seed(TypeRegistrationDeserializer::new(self.registry))? - .ok_or_else(|| Error::invalid_length(0, &"a single entry"))?; - - let value = map.next_value_seed(TypedReflectDeserializer { - registration, - registry: self.registry, - })?; - - if map.next_key::()?.is_some() { - return Err(Error::invalid_length(2, &"a single entry")); - } - - Ok(value) - } - } - - deserializer.deserialize_map(UntypedReflectDeserializerVisitor { - registry: self.registry, - }) - } -} - -/// A deserializer for reflected types whose [`TypeRegistration`] is known. -/// -/// This is the deserializer counterpart to [`TypedReflectSerializer`]. -/// -/// See [`ReflectDeserializer`] for a deserializer that expects an unknown type. -/// -/// # Input -/// -/// Since the type is already known, the input is just the serialized data. -/// -/// # Output -/// -/// This deserializer will return a [`Box`] containing the deserialized data. -/// -/// For value types (i.e. [`ReflectKind::Value`]) or types that register [`ReflectDeserialize`] type data, -/// this `Box` will contain the expected type. -/// For example, deserializing an `i32` will return a `Box` (as a `Box`). -/// -/// Otherwise, this `Box` will contain the dynamic equivalent. -/// For example, a deserialized struct might return a [`Box`] -/// and a deserialized `Vec` might return a [`Box`]. -/// -/// This means that if the actual type is needed, these dynamic representations will need to -/// be converted to the concrete type using [`FromReflect`] or [`ReflectFromReflect`]. -/// -/// # Example -/// -/// ``` -/// # use std::any::TypeId; -/// # use serde::de::DeserializeSeed; -/// # use bevy_reflect::prelude::*; -/// # use bevy_reflect::{DynamicStruct, TypeRegistry, serde::TypedReflectDeserializer}; -/// #[derive(Reflect, PartialEq, Debug)] -/// struct MyStruct { -/// value: i32 -/// } -/// -/// let mut registry = TypeRegistry::default(); -/// registry.register::(); -/// -/// let input = r#"( -/// value: 123 -/// )"#; -/// -/// let registration = registry.get(TypeId::of::()).unwrap(); -/// -/// let mut deserializer = ron::Deserializer::from_str(input).unwrap(); -/// let reflect_deserializer = TypedReflectDeserializer::new(registration, ®istry); -/// -/// let output: Box = reflect_deserializer.deserialize(&mut deserializer).unwrap(); -/// -/// // Since `MyStruct` is not a value type and does not register `ReflectDeserialize`, -/// // we know that its deserialized value will be a `DynamicStruct`, -/// // although it will represent `MyStruct`. -/// assert!(output.as_partial_reflect().represents::()); -/// -/// // We can convert back to `MyStruct` using `FromReflect`. -/// let value: MyStruct = ::from_reflect(output.as_partial_reflect()).unwrap(); -/// assert_eq!(value, MyStruct { value: 123 }); -/// -/// // We can also do this dynamically with `ReflectFromReflect`. -/// let type_id = output.get_represented_type_info().unwrap().type_id(); -/// let reflect_from_reflect = registry.get_type_data::(type_id).unwrap(); -/// let value: Box = reflect_from_reflect.from_reflect(output.as_partial_reflect()).unwrap(); -/// assert!(value.is::()); -/// assert_eq!(value.take::().unwrap(), MyStruct { value: 123 }); -/// ``` -/// -/// [`TypedReflectSerializer`]: crate::serde::TypedReflectSerializer -/// [`Box`]: crate::Reflect -/// [`ReflectKind::Value`]: crate::ReflectKind::Value -/// [`ReflectDeserialize`]: crate::ReflectDeserialize -/// [`Box`]: crate::DynamicStruct -/// [`Box`]: crate::DynamicList -/// [`FromReflect`]: crate::FromReflect -/// [`ReflectFromReflect`]: crate::ReflectFromReflect -pub struct TypedReflectDeserializer<'a> { - registration: &'a TypeRegistration, - registry: &'a TypeRegistry, -} - -impl<'a> TypedReflectDeserializer<'a> { - pub fn new(registration: &'a TypeRegistration, registry: &'a TypeRegistry) -> Self { - Self { - registration, - registry, - } - } -} - -impl<'a, 'de> DeserializeSeed<'de> for TypedReflectDeserializer<'a> { - type Value = Box; - - fn deserialize(self, deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - let type_path = self.registration.type_info().type_path(); - - // Handle both Value case and types that have a custom `ReflectDeserialize` - if let Some(deserialize_reflect) = self.registration.data::() { - let value = deserialize_reflect.deserialize(deserializer)?; - return Ok(value.into_partial_reflect()); - } - - match self.registration.type_info() { - TypeInfo::Struct(struct_info) => { - let mut dynamic_struct = deserializer.deserialize_struct( - struct_info.type_path_table().ident().unwrap(), - struct_info.field_names(), - StructVisitor { - struct_info, - registration: self.registration, - registry: self.registry, - }, - )?; - dynamic_struct.set_represented_type(Some(self.registration.type_info())); - Ok(Box::new(dynamic_struct)) - } - TypeInfo::TupleStruct(tuple_struct_info) => { - let mut dynamic_tuple_struct = deserializer.deserialize_tuple_struct( - tuple_struct_info.type_path_table().ident().unwrap(), - tuple_struct_info.field_len(), - TupleStructVisitor { - tuple_struct_info, - registry: self.registry, - registration: self.registration, - }, - )?; - dynamic_tuple_struct.set_represented_type(Some(self.registration.type_info())); - Ok(Box::new(dynamic_tuple_struct)) - } - TypeInfo::List(list_info) => { - let mut dynamic_list = deserializer.deserialize_seq(ListVisitor { - list_info, - registry: self.registry, - })?; - dynamic_list.set_represented_type(Some(self.registration.type_info())); - Ok(Box::new(dynamic_list)) - } - TypeInfo::Array(array_info) => { - let mut dynamic_array = deserializer.deserialize_tuple( - array_info.capacity(), - ArrayVisitor { - array_info, - registry: self.registry, - }, - )?; - dynamic_array.set_represented_type(Some(self.registration.type_info())); - Ok(Box::new(dynamic_array)) - } - TypeInfo::Map(map_info) => { - let mut dynamic_map = deserializer.deserialize_map(MapVisitor { - map_info, - registry: self.registry, - })?; - dynamic_map.set_represented_type(Some(self.registration.type_info())); - Ok(Box::new(dynamic_map)) - } - TypeInfo::Set(set_info) => { - let mut dynamic_set = deserializer.deserialize_seq(SetVisitor { - set_info, - registry: self.registry, - })?; - dynamic_set.set_represented_type(Some(self.registration.type_info())); - Ok(Box::new(dynamic_set)) - } - TypeInfo::Tuple(tuple_info) => { - let mut dynamic_tuple = deserializer.deserialize_tuple( - tuple_info.field_len(), - TupleVisitor { - tuple_info, - registration: self.registration, - registry: self.registry, - }, - )?; - dynamic_tuple.set_represented_type(Some(self.registration.type_info())); - Ok(Box::new(dynamic_tuple)) - } - TypeInfo::Enum(enum_info) => { - let mut dynamic_enum = if enum_info.type_path_table().module_path() - == Some("core::option") - && enum_info.type_path_table().ident() == Some("Option") - { - deserializer.deserialize_option(OptionVisitor { - enum_info, - registry: self.registry, - })? - } else { - deserializer.deserialize_enum( - enum_info.type_path_table().ident().unwrap(), - enum_info.variant_names(), - EnumVisitor { - enum_info, - registration: self.registration, - registry: self.registry, - }, - )? - }; - dynamic_enum.set_represented_type(Some(self.registration.type_info())); - Ok(Box::new(dynamic_enum)) - } - TypeInfo::Value(_) => { - // This case should already be handled - Err(Error::custom(format_args!( - "Type `{type_path}` did not register the `ReflectDeserialize` type data. For certain types, this may need to be registered manually using `register_type_data`", - ))) - } - } - } -} - -struct StructVisitor<'a> { - struct_info: &'static StructInfo, - registration: &'a TypeRegistration, - registry: &'a TypeRegistry, -} - -impl<'a, 'de> Visitor<'de> for StructVisitor<'a> { - type Value = DynamicStruct; - - fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { - formatter.write_str("reflected struct value") - } - - fn visit_seq(self, mut seq: A) -> Result - where - A: SeqAccess<'de>, - { - visit_struct_seq(&mut seq, self.struct_info, self.registration, self.registry) - } - - fn visit_map(self, mut map: V) -> Result - where - V: MapAccess<'de>, - { - visit_struct(&mut map, self.struct_info, self.registration, self.registry) - } -} - -struct TupleStructVisitor<'a> { - tuple_struct_info: &'static TupleStructInfo, - registry: &'a TypeRegistry, - registration: &'a TypeRegistration, -} - -impl<'a, 'de> Visitor<'de> for TupleStructVisitor<'a> { - type Value = DynamicTupleStruct; - - fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { - formatter.write_str("reflected tuple struct value") - } - - fn visit_seq(self, mut seq: V) -> Result - where - V: SeqAccess<'de>, - { - visit_tuple( - &mut seq, - self.tuple_struct_info, - self.registration, - self.registry, - ) - .map(DynamicTupleStruct::from) - } -} - -struct TupleVisitor<'a> { - tuple_info: &'static TupleInfo, - registration: &'a TypeRegistration, - registry: &'a TypeRegistry, -} - -impl<'a, 'de> Visitor<'de> for TupleVisitor<'a> { - type Value = DynamicTuple; - - fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { - formatter.write_str("reflected tuple value") - } - - fn visit_seq(self, mut seq: V) -> Result - where - V: SeqAccess<'de>, - { - visit_tuple(&mut seq, self.tuple_info, self.registration, self.registry) - } -} - -struct ArrayVisitor<'a> { - array_info: &'static ArrayInfo, - registry: &'a TypeRegistry, -} - -impl<'a, 'de> Visitor<'de> for ArrayVisitor<'a> { - type Value = DynamicArray; - - fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { - formatter.write_str("reflected array value") - } - - fn visit_seq(self, mut seq: V) -> Result - where - V: SeqAccess<'de>, - { - let mut vec = Vec::with_capacity(seq.size_hint().unwrap_or_default()); - let registration = get_registration( - self.array_info.item_ty().id(), - self.array_info.item_ty().path(), - self.registry, - )?; - while let Some(value) = seq.next_element_seed(TypedReflectDeserializer { - registration, - registry: self.registry, - })? { - vec.push(value); - } - - if vec.len() != self.array_info.capacity() { - return Err(Error::invalid_length( - vec.len(), - &self.array_info.capacity().to_string().as_str(), - )); - } - - Ok(DynamicArray::new(vec.into_boxed_slice())) - } -} - -struct ListVisitor<'a> { - list_info: &'static ListInfo, - registry: &'a TypeRegistry, -} - -impl<'a, 'de> Visitor<'de> for ListVisitor<'a> { - type Value = DynamicList; - - fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { - formatter.write_str("reflected list value") - } - - fn visit_seq(self, mut seq: V) -> Result - where - V: SeqAccess<'de>, - { - let mut list = DynamicList::default(); - let registration = get_registration( - self.list_info.item_ty().id(), - self.list_info.item_ty().path(), - self.registry, - )?; - while let Some(value) = seq.next_element_seed(TypedReflectDeserializer { - registration, - registry: self.registry, - })? { - list.push_box(value); - } - Ok(list) - } -} - -struct MapVisitor<'a> { - map_info: &'static MapInfo, - registry: &'a TypeRegistry, -} - -impl<'a, 'de> Visitor<'de> for MapVisitor<'a> { - type Value = DynamicMap; - - fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { - formatter.write_str("reflected map value") - } - - fn visit_map(self, mut map: V) -> Result - where - V: MapAccess<'de>, - { - let mut dynamic_map = DynamicMap::default(); - let key_registration = get_registration( - self.map_info.key_ty().id(), - self.map_info.key_ty().path(), - self.registry, - )?; - let value_registration = get_registration( - self.map_info.value_ty().id(), - self.map_info.value_ty().path(), - self.registry, - )?; - while let Some(key) = map.next_key_seed(TypedReflectDeserializer { - registration: key_registration, - registry: self.registry, - })? { - let value = map.next_value_seed(TypedReflectDeserializer { - registration: value_registration, - registry: self.registry, - })?; - dynamic_map.insert_boxed(key, value); - } - - Ok(dynamic_map) - } -} - -struct SetVisitor<'a> { - set_info: &'static SetInfo, - registry: &'a TypeRegistry, -} - -impl<'a, 'de> Visitor<'de> for SetVisitor<'a> { - type Value = DynamicSet; - - fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { - formatter.write_str("reflected set value") - } - - fn visit_seq(self, mut set: V) -> Result - where - V: SeqAccess<'de>, - { - let mut dynamic_set = DynamicSet::default(); - let value_registration = get_registration( - self.set_info.value_ty().id(), - self.set_info.value_ty().path(), - self.registry, - )?; - while let Some(value) = set.next_element_seed(TypedReflectDeserializer { - registration: value_registration, - registry: self.registry, - })? { - dynamic_set.insert_boxed(value); - } - - Ok(dynamic_set) - } -} - -struct EnumVisitor<'a> { - enum_info: &'static EnumInfo, - registration: &'a TypeRegistration, - registry: &'a TypeRegistry, -} - -impl<'a, 'de> Visitor<'de> for EnumVisitor<'a> { - type Value = DynamicEnum; - - fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { - formatter.write_str("reflected enum value") - } - - fn visit_enum(self, data: A) -> Result - where - A: EnumAccess<'de>, - { - let mut dynamic_enum = DynamicEnum::default(); - let (variant_info, variant) = data.variant_seed(VariantDeserializer { - enum_info: self.enum_info, - })?; - - let value: DynamicVariant = match variant_info { - VariantInfo::Unit(..) => variant.unit_variant()?.into(), - VariantInfo::Struct(struct_info) => variant - .struct_variant( - struct_info.field_names(), - StructVariantVisitor { - struct_info, - registration: self.registration, - registry: self.registry, - }, - )? - .into(), - VariantInfo::Tuple(tuple_info) if tuple_info.field_len() == 1 => { - let registration = tuple_info.get_field_registration(0, self.registry)?; - let value = variant.newtype_variant_seed(TypedReflectDeserializer { - registration, - registry: self.registry, - })?; - let mut dynamic_tuple = DynamicTuple::default(); - dynamic_tuple.insert_boxed(value); - dynamic_tuple.into() - } - VariantInfo::Tuple(tuple_info) => variant - .tuple_variant( - tuple_info.field_len(), - TupleVariantVisitor { - tuple_info, - registration: self.registration, - registry: self.registry, - }, - )? - .into(), - }; - let variant_name = variant_info.name(); - let variant_index = self - .enum_info - .index_of(variant_name) - .expect("variant should exist"); - dynamic_enum.set_variant_with_index(variant_index, variant_name, value); - Ok(dynamic_enum) - } -} - -struct VariantDeserializer { - enum_info: &'static EnumInfo, -} - -impl<'de> DeserializeSeed<'de> for VariantDeserializer { - type Value = &'static VariantInfo; - - fn deserialize(self, deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - struct VariantVisitor(&'static EnumInfo); - - impl<'de> Visitor<'de> for VariantVisitor { - type Value = &'static VariantInfo; - - fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { - formatter.write_str("expected either a variant index or variant name") - } - - fn visit_u32(self, variant_index: u32) -> Result - where - E: Error, - { - self.0.variant_at(variant_index as usize).ok_or_else(|| { - Error::custom(format_args!( - "no variant found at index `{}` on enum `{}`", - variant_index, - self.0.type_path() - )) - }) - } - - fn visit_str(self, variant_name: &str) -> Result - where - E: Error, - { - self.0.variant(variant_name).ok_or_else(|| { - let names = self.0.iter().map(VariantInfo::name); - Error::custom(format_args!( - "unknown variant `{}`, expected one of {:?}", - variant_name, - ExpectedValues(names.collect()) - )) - }) - } - } - - deserializer.deserialize_identifier(VariantVisitor(self.enum_info)) - } -} - -struct StructVariantVisitor<'a> { - struct_info: &'static StructVariantInfo, - registration: &'a TypeRegistration, - registry: &'a TypeRegistry, -} - -impl<'a, 'de> Visitor<'de> for StructVariantVisitor<'a> { - type Value = DynamicStruct; - - fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { - formatter.write_str("reflected struct variant value") - } - - fn visit_seq(self, mut seq: A) -> Result - where - A: SeqAccess<'de>, - { - visit_struct_seq(&mut seq, self.struct_info, self.registration, self.registry) - } - - fn visit_map(self, mut map: V) -> Result - where - V: MapAccess<'de>, - { - visit_struct(&mut map, self.struct_info, self.registration, self.registry) - } -} - -struct TupleVariantVisitor<'a> { - tuple_info: &'static TupleVariantInfo, - registration: &'a TypeRegistration, - registry: &'a TypeRegistry, -} - -impl<'a, 'de> Visitor<'de> for TupleVariantVisitor<'a> { - type Value = DynamicTuple; - - fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { - formatter.write_str("reflected tuple variant value") - } - - fn visit_seq(self, mut seq: V) -> Result - where - V: SeqAccess<'de>, - { - visit_tuple(&mut seq, self.tuple_info, self.registration, self.registry) - } -} - -struct OptionVisitor<'a> { - enum_info: &'static EnumInfo, - registry: &'a TypeRegistry, -} - -impl<'a, 'de> Visitor<'de> for OptionVisitor<'a> { - type Value = DynamicEnum; - - fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { - formatter.write_str("reflected option value of type ")?; - formatter.write_str(self.enum_info.type_path()) - } - - fn visit_none(self) -> Result - where - E: Error, - { - let mut option = DynamicEnum::default(); - option.set_variant("None", ()); - Ok(option) - } - - fn visit_some(self, deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - let variant_info = self.enum_info.variant("Some").unwrap(); - match variant_info { - VariantInfo::Tuple(tuple_info) if tuple_info.field_len() == 1 => { - let field = tuple_info.field_at(0).unwrap(); - let registration = - get_registration(field.type_id(), field.type_path(), self.registry)?; - let de = TypedReflectDeserializer { - registration, - registry: self.registry, - }; - let mut value = DynamicTuple::default(); - value.insert_boxed(de.deserialize(deserializer)?); - let mut option = DynamicEnum::default(); - option.set_variant("Some", value); - Ok(option) - } - info => Err(Error::custom(format_args!( - "invalid variant, expected `Some` but got `{}`", - info.name() - ))), - } - } -} - -fn visit_struct<'de, T, V>( - map: &mut V, - info: &'static T, - registration: &TypeRegistration, - registry: &TypeRegistry, -) -> Result -where - T: StructLikeInfo, - V: MapAccess<'de>, -{ - let mut dynamic_struct = DynamicStruct::default(); - while let Some(Ident(key)) = map.next_key::()? { - let field = info.get_field(&key).ok_or_else(|| { - let fields = info.iter_fields().map(NamedField::name); - Error::custom(format_args!( - "unknown field `{}`, expected one of {:?}", - key, - ExpectedValues(fields.collect()) - )) - })?; - let registration = get_registration(field.type_id(), field.type_path(), registry)?; - let value = map.next_value_seed(TypedReflectDeserializer { - registration, - registry, - })?; - dynamic_struct.insert_boxed(&key, value); - } - - if let Some(serialization_data) = registration.data::() { - for (skipped_index, skipped_field) in serialization_data.iter_skipped() { - let Some(field) = info.field_at(*skipped_index) else { - continue; - }; - dynamic_struct.insert_boxed( - field.name(), - skipped_field.generate_default().into_partial_reflect(), - ); - } - } - - Ok(dynamic_struct) -} - -fn visit_tuple<'de, T, V>( - seq: &mut V, - info: &T, - registration: &TypeRegistration, - registry: &TypeRegistry, -) -> Result -where - T: TupleLikeInfo + Container, - V: SeqAccess<'de>, -{ - let mut tuple = DynamicTuple::default(); - - let len = info.get_field_len(); - - if len == 0 { - // Handle empty tuple/tuple struct - return Ok(tuple); - } - - let serialization_data = registration.data::(); - - for index in 0..len { - if let Some(value) = serialization_data.and_then(|data| data.generate_default(index)) { - tuple.insert_boxed(value.into_partial_reflect()); - continue; - } - - let value = seq - .next_element_seed(TypedReflectDeserializer { - registration: info.get_field_registration(index, registry)?, - registry, - })? - .ok_or_else(|| Error::invalid_length(index, &len.to_string().as_str()))?; - tuple.insert_boxed(value); - } - - Ok(tuple) -} - -fn visit_struct_seq<'de, T, V>( - seq: &mut V, - info: &T, - registration: &TypeRegistration, - registry: &TypeRegistry, -) -> Result -where - T: StructLikeInfo + Container, - V: SeqAccess<'de>, -{ - let mut dynamic_struct = DynamicStruct::default(); - - let len = info.get_field_len(); - - if len == 0 { - // Handle unit structs - return Ok(dynamic_struct); - } - - let serialization_data = registration.data::(); - - for index in 0..len { - let name = info.field_at(index).unwrap().name(); - - if serialization_data - .map(|data| data.is_field_skipped(index)) - .unwrap_or_default() - { - if let Some(value) = serialization_data.unwrap().generate_default(index) { - dynamic_struct.insert_boxed(name, value.into_partial_reflect()); - } - continue; - } - - let value = seq - .next_element_seed(TypedReflectDeserializer { - registration: info.get_field_registration(index, registry)?, - registry, - })? - .ok_or_else(|| Error::invalid_length(index, &len.to_string().as_str()))?; - dynamic_struct.insert_boxed(name, value); - } - - Ok(dynamic_struct) -} - -fn get_registration<'a, E: Error>( - type_id: TypeId, - type_path: &str, - registry: &'a TypeRegistry, -) -> Result<&'a TypeRegistration, E> { - let registration = registry.get(type_id).ok_or_else(|| { - Error::custom(format_args!("no registration found for type `{type_path}`")) - })?; - Ok(registration) -} - -#[cfg(test)] -mod tests { - use bincode::Options; - use std::any::TypeId; - use std::f32::consts::PI; - use std::ops::RangeInclusive; - - use serde::de::DeserializeSeed; - use serde::Deserialize; - - use bevy_utils::{HashMap, HashSet}; - - use crate as bevy_reflect; - use crate::serde::{ReflectDeserializer, ReflectSerializer, TypedReflectDeserializer}; - use crate::{ - DynamicEnum, FromReflect, PartialReflect, Reflect, ReflectDeserialize, TypeRegistry, - }; - - #[derive(Reflect, Debug, PartialEq)] - struct MyStruct { - primitive_value: i8, - option_value: Option, - option_value_complex: Option, - tuple_value: (f32, usize), - list_value: Vec, - array_value: [i32; 5], - map_value: HashMap, - set_value: HashSet, - struct_value: SomeStruct, - tuple_struct_value: SomeTupleStruct, - unit_struct: SomeUnitStruct, - unit_enum: SomeEnum, - newtype_enum: SomeEnum, - tuple_enum: SomeEnum, - struct_enum: SomeEnum, - ignored_struct: SomeIgnoredStruct, - ignored_tuple_struct: SomeIgnoredTupleStruct, - ignored_struct_variant: SomeIgnoredEnum, - ignored_tuple_variant: SomeIgnoredEnum, - custom_deserialize: CustomDeserialize, - } - - #[derive(Reflect, Debug, PartialEq)] - struct SomeStruct { - foo: i64, - } - - #[derive(Reflect, Debug, PartialEq)] - struct SomeTupleStruct(String); - - #[derive(Reflect, Debug, PartialEq)] - struct SomeUnitStruct; - - #[derive(Reflect, Debug, PartialEq)] - struct SomeIgnoredStruct { - #[reflect(ignore)] - ignored: i32, - } - - #[derive(Reflect, Debug, PartialEq)] - struct SomeIgnoredTupleStruct(#[reflect(ignore)] i32); - - #[derive(Reflect, Debug, PartialEq, Deserialize)] - struct SomeDeserializableStruct { - foo: i64, - } - - /// Implements a custom deserialize using `#[reflect(Deserialize)]`. - /// - /// For testing purposes, this is just the auto-generated one from deriving. - #[derive(Reflect, Debug, PartialEq, Deserialize)] - #[reflect(Deserialize)] - struct CustomDeserialize { - value: usize, - #[serde(alias = "renamed")] - inner_struct: SomeDeserializableStruct, - } - - #[derive(Reflect, Debug, PartialEq)] - enum SomeEnum { - Unit, - NewType(usize), - Tuple(f32, f32), - Struct { foo: String }, - } - - #[derive(Reflect, Debug, PartialEq)] - enum SomeIgnoredEnum { - Tuple(#[reflect(ignore)] f32, #[reflect(ignore)] f32), - Struct { - #[reflect(ignore)] - foo: String, - }, - } - - fn get_registry() -> TypeRegistry { - let mut registry = TypeRegistry::default(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::<(f32, usize)>(); - registry.register::<[i32; 5]>(); - registry.register::>(); - registry.register::>(); - registry.register::>(); - registry.register::>(); - registry.register::>(); - registry.register_type_data::, ReflectDeserialize>(); - registry - } - - fn get_my_struct() -> MyStruct { - let mut map = HashMap::new(); - map.insert(64, 32); - - let mut set = HashSet::new(); - set.insert(64); - - MyStruct { - primitive_value: 123, - option_value: Some(String::from("Hello world!")), - option_value_complex: Some(SomeStruct { foo: 123 }), - tuple_value: (PI, 1337), - list_value: vec![-2, -1, 0, 1, 2], - array_value: [-2, -1, 0, 1, 2], - map_value: map, - set_value: set, - struct_value: SomeStruct { foo: 999999999 }, - tuple_struct_value: SomeTupleStruct(String::from("Tuple Struct")), - unit_struct: SomeUnitStruct, - unit_enum: SomeEnum::Unit, - newtype_enum: SomeEnum::NewType(123), - tuple_enum: SomeEnum::Tuple(1.23, 3.21), - struct_enum: SomeEnum::Struct { - foo: String::from("Struct variant value"), - }, - ignored_struct: SomeIgnoredStruct { ignored: 0 }, - ignored_tuple_struct: SomeIgnoredTupleStruct(0), - ignored_struct_variant: SomeIgnoredEnum::Struct { - foo: String::default(), - }, - ignored_tuple_variant: SomeIgnoredEnum::Tuple(0.0, 0.0), - custom_deserialize: CustomDeserialize { - value: 100, - inner_struct: SomeDeserializableStruct { foo: 101 }, - }, - } - } - - #[test] - fn should_deserialize() { - let expected = get_my_struct(); - let registry = get_registry(); - - let input = r#"{ - "bevy_reflect::serde::de::tests::MyStruct": ( - primitive_value: 123, - option_value: Some("Hello world!"), - option_value_complex: Some(( - foo: 123, - )), - tuple_value: (3.1415927, 1337), - list_value: [ - -2, - -1, - 0, - 1, - 2, - ], - array_value: (-2, -1, 0, 1, 2), - map_value: { - 64: 32, - }, - set_value: [ - 64, - ], - struct_value: ( - foo: 999999999, - ), - tuple_struct_value: ("Tuple Struct"), - unit_struct: (), - unit_enum: Unit, - newtype_enum: NewType(123), - tuple_enum: Tuple(1.23, 3.21), - struct_enum: Struct( - foo: "Struct variant value", - ), - ignored_struct: (), - ignored_tuple_struct: (), - ignored_struct_variant: Struct(), - ignored_tuple_variant: Tuple(), - custom_deserialize: ( - value: 100, - renamed: ( - foo: 101, - ), - ), - ), - }"#; - - let reflect_deserializer = ReflectDeserializer::new(®istry); - let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap(); - let dynamic_output = reflect_deserializer - .deserialize(&mut ron_deserializer) - .unwrap(); - - let output = ::from_reflect(dynamic_output.as_ref()).unwrap(); - assert_eq!(expected, output); - } - - #[test] - fn should_deserialize_value() { - let input = r#"{ - "f32": 1.23, - }"#; - - let registry = get_registry(); - let reflect_deserializer = ReflectDeserializer::new(®istry); - let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap(); - let dynamic_output = reflect_deserializer - .deserialize(&mut ron_deserializer) - .unwrap(); - let output = dynamic_output - .try_take::() - .expect("underlying type should be f32"); - assert_eq!(1.23, output); - } - - #[test] - fn should_deserialized_typed() { - #[derive(Reflect, Debug, PartialEq)] - struct Foo { - bar: i32, - } - - let expected = Foo { bar: 123 }; - - let input = r#"( - bar: 123 - )"#; - - let mut registry = get_registry(); - registry.register::(); - let registration = registry.get(TypeId::of::()).unwrap(); - let reflect_deserializer = TypedReflectDeserializer::new(registration, ®istry); - let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap(); - let dynamic_output = reflect_deserializer - .deserialize(&mut ron_deserializer) - .unwrap(); - - let output = - ::from_reflect(dynamic_output.as_ref().as_partial_reflect()) - .unwrap(); - assert_eq!(expected, output); - } - - #[test] - fn should_deserialize_option() { - #[derive(Reflect, Debug, PartialEq)] - struct OptionTest { - none: Option<()>, - simple: Option, - complex: Option, - } - - let expected = OptionTest { - none: None, - simple: Some(String::from("Hello world!")), - complex: Some(SomeStruct { foo: 123 }), - }; - - let mut registry = get_registry(); - registry.register::(); - registry.register::>(); - - // === Normal === // - let input = r#"{ - "bevy_reflect::serde::de::tests::OptionTest": ( - none: None, - simple: Some("Hello world!"), - complex: Some(( - foo: 123, - )), - ), - }"#; - - let reflect_deserializer = ReflectDeserializer::new(®istry); - let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap(); - let dynamic_output = reflect_deserializer - .deserialize(&mut ron_deserializer) - .unwrap(); - - let output = ::from_reflect(dynamic_output.as_ref()).unwrap(); - assert_eq!(expected, output, "failed to deserialize Options"); - - // === Implicit Some === // - let input = r#" - #![enable(implicit_some)] - { - "bevy_reflect::serde::de::tests::OptionTest": ( - none: None, - simple: "Hello world!", - complex: ( - foo: 123, - ), - ), - }"#; - - let reflect_deserializer = ReflectDeserializer::new(®istry); - let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap(); - let dynamic_output = reflect_deserializer - .deserialize(&mut ron_deserializer) - .unwrap(); - - let output = ::from_reflect(dynamic_output.as_ref()).unwrap(); - assert_eq!( - expected, output, - "failed to deserialize Options with implicit Some" - ); - } - - #[test] - fn enum_should_deserialize() { - #[derive(Reflect)] - enum MyEnum { - Unit, - NewType(usize), - Tuple(f32, f32), - Struct { value: String }, - } - - let mut registry = get_registry(); - registry.register::(); - - // === Unit Variant === // - let input = r#"{ - "bevy_reflect::serde::de::tests::MyEnum": Unit, -}"#; - let reflect_deserializer = ReflectDeserializer::new(®istry); - let mut deserializer = ron::de::Deserializer::from_str(input).unwrap(); - let output = reflect_deserializer.deserialize(&mut deserializer).unwrap(); - - let expected = DynamicEnum::from(MyEnum::Unit); - assert!(expected.reflect_partial_eq(output.as_ref()).unwrap()); - - // === NewType Variant === // - let input = r#"{ - "bevy_reflect::serde::de::tests::MyEnum": NewType(123), -}"#; - let reflect_deserializer = ReflectDeserializer::new(®istry); - let mut deserializer = ron::de::Deserializer::from_str(input).unwrap(); - let output = reflect_deserializer.deserialize(&mut deserializer).unwrap(); - - let expected = DynamicEnum::from(MyEnum::NewType(123)); - assert!(expected.reflect_partial_eq(output.as_ref()).unwrap()); - - // === Tuple Variant === // - let input = r#"{ - "bevy_reflect::serde::de::tests::MyEnum": Tuple(1.23, 3.21), -}"#; - let reflect_deserializer = ReflectDeserializer::new(®istry); - let mut deserializer = ron::de::Deserializer::from_str(input).unwrap(); - let output = reflect_deserializer.deserialize(&mut deserializer).unwrap(); - - let expected = DynamicEnum::from(MyEnum::Tuple(1.23, 3.21)); - assert!(expected - .reflect_partial_eq(output.as_partial_reflect()) - .unwrap()); - - // === Struct Variant === // - let input = r#"{ - "bevy_reflect::serde::de::tests::MyEnum": Struct( - value: "I <3 Enums", - ), -}"#; - let reflect_deserializer = ReflectDeserializer::new(®istry); - let mut deserializer = ron::de::Deserializer::from_str(input).unwrap(); - let output = reflect_deserializer.deserialize(&mut deserializer).unwrap(); - - let expected = DynamicEnum::from(MyEnum::Struct { - value: String::from("I <3 Enums"), - }); - assert!(expected - .reflect_partial_eq(output.as_partial_reflect()) - .unwrap()); - } - - // Regression test for https://github.com/bevyengine/bevy/issues/12462 - #[test] - fn should_reserialize() { - let registry = get_registry(); - let input1 = get_my_struct(); - - let serializer1 = ReflectSerializer::new(&input1, ®istry); - let serialized1 = ron::ser::to_string(&serializer1).unwrap(); - - let mut deserializer = ron::de::Deserializer::from_str(&serialized1).unwrap(); - let reflect_deserializer = ReflectDeserializer::new(®istry); - let input2 = reflect_deserializer.deserialize(&mut deserializer).unwrap(); - - let serializer2 = ReflectSerializer::new(input2.as_partial_reflect(), ®istry); - let serialized2 = ron::ser::to_string(&serializer2).unwrap(); - - assert_eq!(serialized1, serialized2); - } - - #[test] - fn should_deserialize_non_self_describing_binary() { - let expected = get_my_struct(); - let registry = get_registry(); - - let input = vec![ - 1, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 98, 101, 118, 121, 95, 114, 101, 102, - 108, 101, 99, 116, 58, 58, 115, 101, 114, 100, 101, 58, 58, 100, 101, 58, 58, 116, 101, - 115, 116, 115, 58, 58, 77, 121, 83, 116, 114, 117, 99, 116, 123, 1, 12, 0, 0, 0, 0, 0, - 0, 0, 72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33, 1, 123, 0, 0, 0, 0, 0, - 0, 0, 219, 15, 73, 64, 57, 5, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 254, 255, 255, - 255, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 254, 255, 255, 255, 255, - 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 32, 0, - 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 255, 201, 154, 59, 0, 0, 0, 0, 12, 0, 0, - 0, 0, 0, 0, 0, 84, 117, 112, 108, 101, 32, 83, 116, 114, 117, 99, 116, 0, 0, 0, 0, 1, - 0, 0, 0, 123, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 164, 112, 157, 63, 164, 112, 77, 64, 3, - 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 83, 116, 114, 117, 99, 116, 32, 118, 97, 114, 105, - 97, 110, 116, 32, 118, 97, 108, 117, 101, 1, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, - 0, 0, 101, 0, 0, 0, 0, 0, 0, 0, - ]; - - let deserializer = ReflectDeserializer::new(®istry); - - let dynamic_output = bincode::DefaultOptions::new() - .with_fixint_encoding() - .deserialize_seed(deserializer, &input) - .unwrap(); - - let output = ::from_reflect(dynamic_output.as_ref()).unwrap(); - assert_eq!(expected, output); - } - - #[test] - fn should_deserialize_self_describing_binary() { - let expected = get_my_struct(); - let registry = get_registry(); - - let input = vec![ - 129, 217, 40, 98, 101, 118, 121, 95, 114, 101, 102, 108, 101, 99, 116, 58, 58, 115, - 101, 114, 100, 101, 58, 58, 100, 101, 58, 58, 116, 101, 115, 116, 115, 58, 58, 77, 121, - 83, 116, 114, 117, 99, 116, 220, 0, 20, 123, 172, 72, 101, 108, 108, 111, 32, 119, 111, - 114, 108, 100, 33, 145, 123, 146, 202, 64, 73, 15, 219, 205, 5, 57, 149, 254, 255, 0, - 1, 2, 149, 254, 255, 0, 1, 2, 129, 64, 32, 145, 64, 145, 206, 59, 154, 201, 255, 145, - 172, 84, 117, 112, 108, 101, 32, 83, 116, 114, 117, 99, 116, 144, 164, 85, 110, 105, - 116, 129, 167, 78, 101, 119, 84, 121, 112, 101, 123, 129, 165, 84, 117, 112, 108, 101, - 146, 202, 63, 157, 112, 164, 202, 64, 77, 112, 164, 129, 166, 83, 116, 114, 117, 99, - 116, 145, 180, 83, 116, 114, 117, 99, 116, 32, 118, 97, 114, 105, 97, 110, 116, 32, - 118, 97, 108, 117, 101, 144, 144, 129, 166, 83, 116, 114, 117, 99, 116, 144, 129, 165, - 84, 117, 112, 108, 101, 144, 146, 100, 145, 101, - ]; - - let mut reader = std::io::BufReader::new(input.as_slice()); - - let deserializer = ReflectDeserializer::new(®istry); - let dynamic_output = deserializer - .deserialize(&mut rmp_serde::Deserializer::new(&mut reader)) - .unwrap(); - - let output = ::from_reflect(dynamic_output.as_ref()).unwrap(); - assert_eq!(expected, output); - } - - #[test] - fn should_return_error_if_missing_type_data() { - let mut registry = TypeRegistry::new(); - registry.register::>(); - - let input = r#"{"core::ops::RangeInclusive":(start:0.0,end:1.0)}"#; - let mut deserializer = ron::de::Deserializer::from_str(input).unwrap(); - let reflect_deserializer = ReflectDeserializer::new(®istry); - let error = reflect_deserializer - .deserialize(&mut deserializer) - .unwrap_err(); - assert_eq!(error, ron::Error::Message("Type `core::ops::RangeInclusive` did not register the `ReflectDeserialize` type data. For certain types, this may need to be registered manually using `register_type_data`".to_string())); - } -} diff --git a/crates/bevy_reflect/src/serde/de/arrays.rs b/crates/bevy_reflect/src/serde/de/arrays.rs new file mode 100644 index 0000000000..6e2f331a65 --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/arrays.rs @@ -0,0 +1,53 @@ +use crate::serde::de::registration_utils::try_get_registration; +use crate::serde::TypedReflectDeserializer; +use crate::{ArrayInfo, DynamicArray, TypeRegistry}; +use core::fmt::Formatter; +use serde::de::{Error, SeqAccess, Visitor}; +use std::fmt; + +/// A [`Visitor`] for deserializing [`Array`] values. +/// +/// [`Array`]: crate::Array +pub(super) struct ArrayVisitor<'a> { + array_info: &'static ArrayInfo, + registry: &'a TypeRegistry, +} + +impl<'a> ArrayVisitor<'a> { + pub fn new(array_info: &'static ArrayInfo, registry: &'a TypeRegistry) -> Self { + Self { + array_info, + registry, + } + } +} + +impl<'a, 'de> Visitor<'de> for ArrayVisitor<'a> { + type Value = DynamicArray; + + fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { + formatter.write_str("reflected array value") + } + + fn visit_seq(self, mut seq: V) -> Result + where + V: SeqAccess<'de>, + { + let mut vec = Vec::with_capacity(seq.size_hint().unwrap_or_default()); + let registration = try_get_registration(self.array_info.item_ty(), self.registry)?; + while let Some(value) = + seq.next_element_seed(TypedReflectDeserializer::new(registration, self.registry))? + { + vec.push(value); + } + + if vec.len() != self.array_info.capacity() { + return Err(Error::invalid_length( + vec.len(), + &self.array_info.capacity().to_string().as_str(), + )); + } + + Ok(DynamicArray::new(vec.into_boxed_slice())) + } +} diff --git a/crates/bevy_reflect/src/serde/de/deserializer.rs b/crates/bevy_reflect/src/serde/de/deserializer.rs new file mode 100644 index 0000000000..a4496dc72d --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/deserializer.rs @@ -0,0 +1,333 @@ +use crate::serde::de::arrays::ArrayVisitor; +use crate::serde::de::enums::EnumVisitor; +use crate::serde::de::lists::ListVisitor; +use crate::serde::de::maps::MapVisitor; +use crate::serde::de::options::OptionVisitor; +use crate::serde::de::sets::SetVisitor; +use crate::serde::de::structs::StructVisitor; +use crate::serde::de::tuple_structs::TupleStructVisitor; +use crate::serde::de::tuples::TupleVisitor; +use crate::serde::TypeRegistrationDeserializer; +use crate::{PartialReflect, ReflectDeserialize, TypeInfo, TypeRegistration, TypeRegistry}; +use core::fmt::Formatter; +use serde::de::{DeserializeSeed, Error, IgnoredAny, MapAccess, Visitor}; +use std::fmt; + +/// A general purpose deserializer for reflected types. +/// +/// This is the deserializer counterpart to [`ReflectSerializer`]. +/// +/// See [`TypedReflectDeserializer`] for a deserializer that expects a known type. +/// +/// # Input +/// +/// This deserializer expects a map with a single entry, +/// where the key is the _full_ [type path] of the reflected type +/// and the value is the serialized data. +/// +/// # Output +/// +/// This deserializer will return a [`Box`] containing the deserialized data. +/// +/// For value types (i.e. [`ReflectKind::Value`]) or types that register [`ReflectDeserialize`] type data, +/// this `Box` will contain the expected type. +/// For example, deserializing an `i32` will return a `Box` (as a `Box`). +/// +/// Otherwise, this `Box` will contain the dynamic equivalent. +/// For example, a deserialized struct might return a [`Box`] +/// and a deserialized `Vec` might return a [`Box`]. +/// +/// This means that if the actual type is needed, these dynamic representations will need to +/// be converted to the concrete type using [`FromReflect`] or [`ReflectFromReflect`]. +/// +/// # Example +/// +/// ``` +/// # use serde::de::DeserializeSeed; +/// # use bevy_reflect::prelude::*; +/// # use bevy_reflect::{DynamicStruct, TypeRegistry, serde::ReflectDeserializer}; +/// #[derive(Reflect, PartialEq, Debug)] +/// #[type_path = "my_crate"] +/// struct MyStruct { +/// value: i32 +/// } +/// +/// let mut registry = TypeRegistry::default(); +/// registry.register::(); +/// +/// let input = r#"{ +/// "my_crate::MyStruct": ( +/// value: 123 +/// ) +/// }"#; +/// +/// let mut deserializer = ron::Deserializer::from_str(input).unwrap(); +/// let reflect_deserializer = ReflectDeserializer::new(®istry); +/// +/// let output: Box = reflect_deserializer.deserialize(&mut deserializer).unwrap(); +/// +/// // Since `MyStruct` is not a value type and does not register `ReflectDeserialize`, +/// // we know that its deserialized value will be a `DynamicStruct`, +/// // although it will represent `MyStruct`. +/// assert!(output.as_partial_reflect().represents::()); +/// +/// // We can convert back to `MyStruct` using `FromReflect`. +/// let value: MyStruct = ::from_reflect(output.as_partial_reflect()).unwrap(); +/// assert_eq!(value, MyStruct { value: 123 }); +/// +/// // We can also do this dynamically with `ReflectFromReflect`. +/// let type_id = output.get_represented_type_info().unwrap().type_id(); +/// let reflect_from_reflect = registry.get_type_data::(type_id).unwrap(); +/// let value: Box = reflect_from_reflect.from_reflect(output.as_partial_reflect()).unwrap(); +/// assert!(value.is::()); +/// assert_eq!(value.take::().unwrap(), MyStruct { value: 123 }); +/// ``` +/// +/// [`ReflectSerializer`]: crate::serde::ReflectSerializer +/// [type path]: crate::TypePath::type_path +/// [`Box`]: crate::Reflect +/// [`ReflectKind::Value`]: crate::ReflectKind::Value +/// [`ReflectDeserialize`]: crate::ReflectDeserialize +/// [`Box`]: crate::DynamicStruct +/// [`Box`]: crate::DynamicList +/// [`FromReflect`]: crate::FromReflect +/// [`ReflectFromReflect`]: crate::ReflectFromReflect +pub struct ReflectDeserializer<'a> { + registry: &'a TypeRegistry, +} + +impl<'a> ReflectDeserializer<'a> { + pub fn new(registry: &'a TypeRegistry) -> Self { + Self { registry } + } +} + +impl<'a, 'de> DeserializeSeed<'de> for ReflectDeserializer<'a> { + type Value = Box; + + fn deserialize(self, deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + struct UntypedReflectDeserializerVisitor<'a> { + registry: &'a TypeRegistry, + } + + impl<'a, 'de> Visitor<'de> for UntypedReflectDeserializerVisitor<'a> { + type Value = Box; + + fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { + formatter + .write_str("map containing `type` and `value` entries for the reflected value") + } + + fn visit_map(self, mut map: A) -> Result + where + A: MapAccess<'de>, + { + let registration = map + .next_key_seed(TypeRegistrationDeserializer::new(self.registry))? + .ok_or_else(|| Error::invalid_length(0, &"a single entry"))?; + + let value = map.next_value_seed(TypedReflectDeserializer { + registration, + registry: self.registry, + })?; + + if map.next_key::()?.is_some() { + return Err(Error::invalid_length(2, &"a single entry")); + } + + Ok(value) + } + } + + deserializer.deserialize_map(UntypedReflectDeserializerVisitor { + registry: self.registry, + }) + } +} + +/// A deserializer for reflected types whose [`TypeRegistration`] is known. +/// +/// This is the deserializer counterpart to [`TypedReflectSerializer`]. +/// +/// See [`ReflectDeserializer`] for a deserializer that expects an unknown type. +/// +/// # Input +/// +/// Since the type is already known, the input is just the serialized data. +/// +/// # Output +/// +/// This deserializer will return a [`Box`] containing the deserialized data. +/// +/// For value types (i.e. [`ReflectKind::Value`]) or types that register [`ReflectDeserialize`] type data, +/// this `Box` will contain the expected type. +/// For example, deserializing an `i32` will return a `Box` (as a `Box`). +/// +/// Otherwise, this `Box` will contain the dynamic equivalent. +/// For example, a deserialized struct might return a [`Box`] +/// and a deserialized `Vec` might return a [`Box`]. +/// +/// This means that if the actual type is needed, these dynamic representations will need to +/// be converted to the concrete type using [`FromReflect`] or [`ReflectFromReflect`]. +/// +/// # Example +/// +/// ``` +/// # use std::any::TypeId; +/// # use serde::de::DeserializeSeed; +/// # use bevy_reflect::prelude::*; +/// # use bevy_reflect::{DynamicStruct, TypeRegistry, serde::TypedReflectDeserializer}; +/// #[derive(Reflect, PartialEq, Debug)] +/// struct MyStruct { +/// value: i32 +/// } +/// +/// let mut registry = TypeRegistry::default(); +/// registry.register::(); +/// +/// let input = r#"( +/// value: 123 +/// )"#; +/// +/// let registration = registry.get(TypeId::of::()).unwrap(); +/// +/// let mut deserializer = ron::Deserializer::from_str(input).unwrap(); +/// let reflect_deserializer = TypedReflectDeserializer::new(registration, ®istry); +/// +/// let output: Box = reflect_deserializer.deserialize(&mut deserializer).unwrap(); +/// +/// // Since `MyStruct` is not a value type and does not register `ReflectDeserialize`, +/// // we know that its deserialized value will be a `DynamicStruct`, +/// // although it will represent `MyStruct`. +/// assert!(output.as_partial_reflect().represents::()); +/// +/// // We can convert back to `MyStruct` using `FromReflect`. +/// let value: MyStruct = ::from_reflect(output.as_partial_reflect()).unwrap(); +/// assert_eq!(value, MyStruct { value: 123 }); +/// +/// // We can also do this dynamically with `ReflectFromReflect`. +/// let type_id = output.get_represented_type_info().unwrap().type_id(); +/// let reflect_from_reflect = registry.get_type_data::(type_id).unwrap(); +/// let value: Box = reflect_from_reflect.from_reflect(output.as_partial_reflect()).unwrap(); +/// assert!(value.is::()); +/// assert_eq!(value.take::().unwrap(), MyStruct { value: 123 }); +/// ``` +/// +/// [`TypedReflectSerializer`]: crate::serde::TypedReflectSerializer +/// [`Box`]: crate::Reflect +/// [`ReflectKind::Value`]: crate::ReflectKind::Value +/// [`ReflectDeserialize`]: crate::ReflectDeserialize +/// [`Box`]: crate::DynamicStruct +/// [`Box`]: crate::DynamicList +/// [`FromReflect`]: crate::FromReflect +/// [`ReflectFromReflect`]: crate::ReflectFromReflect +pub struct TypedReflectDeserializer<'a> { + registration: &'a TypeRegistration, + registry: &'a TypeRegistry, +} + +impl<'a> TypedReflectDeserializer<'a> { + pub fn new(registration: &'a TypeRegistration, registry: &'a TypeRegistry) -> Self { + Self { + registration, + registry, + } + } +} + +impl<'a, 'de> DeserializeSeed<'de> for TypedReflectDeserializer<'a> { + type Value = Box; + + fn deserialize(self, deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let type_path = self.registration.type_info().type_path(); + + // Handle both Value case and types that have a custom `ReflectDeserialize` + if let Some(deserialize_reflect) = self.registration.data::() { + let value = deserialize_reflect.deserialize(deserializer)?; + return Ok(value.into_partial_reflect()); + } + + match self.registration.type_info() { + TypeInfo::Struct(struct_info) => { + let mut dynamic_struct = deserializer.deserialize_struct( + struct_info.type_path_table().ident().unwrap(), + struct_info.field_names(), + StructVisitor::new(struct_info, self.registration, self.registry), + )?; + dynamic_struct.set_represented_type(Some(self.registration.type_info())); + Ok(Box::new(dynamic_struct)) + } + TypeInfo::TupleStruct(tuple_struct_info) => { + let mut dynamic_tuple_struct = deserializer.deserialize_tuple_struct( + tuple_struct_info.type_path_table().ident().unwrap(), + tuple_struct_info.field_len(), + TupleStructVisitor::new(tuple_struct_info, self.registration, self.registry), + )?; + dynamic_tuple_struct.set_represented_type(Some(self.registration.type_info())); + Ok(Box::new(dynamic_tuple_struct)) + } + TypeInfo::List(list_info) => { + let mut dynamic_list = + deserializer.deserialize_seq(ListVisitor::new(list_info, self.registry))?; + dynamic_list.set_represented_type(Some(self.registration.type_info())); + Ok(Box::new(dynamic_list)) + } + TypeInfo::Array(array_info) => { + let mut dynamic_array = deserializer.deserialize_tuple( + array_info.capacity(), + ArrayVisitor::new(array_info, self.registry), + )?; + dynamic_array.set_represented_type(Some(self.registration.type_info())); + Ok(Box::new(dynamic_array)) + } + TypeInfo::Map(map_info) => { + let mut dynamic_map = + deserializer.deserialize_map(MapVisitor::new(map_info, self.registry))?; + dynamic_map.set_represented_type(Some(self.registration.type_info())); + Ok(Box::new(dynamic_map)) + } + TypeInfo::Set(set_info) => { + let mut dynamic_set = + deserializer.deserialize_seq(SetVisitor::new(set_info, self.registry))?; + dynamic_set.set_represented_type(Some(self.registration.type_info())); + Ok(Box::new(dynamic_set)) + } + TypeInfo::Tuple(tuple_info) => { + let mut dynamic_tuple = deserializer.deserialize_tuple( + tuple_info.field_len(), + TupleVisitor::new(tuple_info, self.registration, self.registry), + )?; + dynamic_tuple.set_represented_type(Some(self.registration.type_info())); + Ok(Box::new(dynamic_tuple)) + } + TypeInfo::Enum(enum_info) => { + let mut dynamic_enum = if enum_info.type_path_table().module_path() + == Some("core::option") + && enum_info.type_path_table().ident() == Some("Option") + { + deserializer.deserialize_option(OptionVisitor::new(enum_info, self.registry))? + } else { + deserializer.deserialize_enum( + enum_info.type_path_table().ident().unwrap(), + enum_info.variant_names(), + EnumVisitor::new(enum_info, self.registration, self.registry), + )? + }; + dynamic_enum.set_represented_type(Some(self.registration.type_info())); + Ok(Box::new(dynamic_enum)) + } + TypeInfo::Value(_) => { + // This case should already be handled + Err(Error::custom(format_args!( + "Type `{type_path}` did not register the `ReflectDeserialize` type data. For certain types, this may need to be registered manually using `register_type_data`", + ))) + } + } + } +} diff --git a/crates/bevy_reflect/src/serde/de/enums.rs b/crates/bevy_reflect/src/serde/de/enums.rs new file mode 100644 index 0000000000..9350ebce6f --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/enums.rs @@ -0,0 +1,198 @@ +use crate::serde::de::helpers::ExpectedValues; +use crate::serde::de::registration_utils::try_get_registration; +use crate::serde::de::struct_utils::{visit_struct, visit_struct_seq}; +use crate::serde::de::tuple_utils::{visit_tuple, TupleLikeInfo}; +use crate::serde::TypedReflectDeserializer; +use crate::{ + DynamicEnum, DynamicStruct, DynamicTuple, DynamicVariant, EnumInfo, StructVariantInfo, + TupleVariantInfo, TypeRegistration, TypeRegistry, VariantInfo, +}; +use core::fmt::Formatter; +use serde::de::{DeserializeSeed, EnumAccess, Error, MapAccess, SeqAccess, VariantAccess, Visitor}; +use std::fmt; + +/// A [`Visitor`] for deserializing [`Enum`] values. +/// +/// [`Enum`]: crate::Enum +pub(super) struct EnumVisitor<'a> { + enum_info: &'static EnumInfo, + registration: &'a TypeRegistration, + registry: &'a TypeRegistry, +} + +impl<'a> EnumVisitor<'a> { + pub fn new( + enum_info: &'static EnumInfo, + registration: &'a TypeRegistration, + registry: &'a TypeRegistry, + ) -> Self { + Self { + enum_info, + registration, + registry, + } + } +} + +impl<'a, 'de> Visitor<'de> for EnumVisitor<'a> { + type Value = DynamicEnum; + + fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { + formatter.write_str("reflected enum value") + } + + fn visit_enum(self, data: A) -> Result + where + A: EnumAccess<'de>, + { + let mut dynamic_enum = DynamicEnum::default(); + let (variant_info, variant) = data.variant_seed(VariantDeserializer { + enum_info: self.enum_info, + })?; + + let value: DynamicVariant = match variant_info { + VariantInfo::Unit(..) => variant.unit_variant()?.into(), + VariantInfo::Struct(struct_info) => variant + .struct_variant( + struct_info.field_names(), + StructVariantVisitor { + struct_info, + registration: self.registration, + registry: self.registry, + }, + )? + .into(), + VariantInfo::Tuple(tuple_info) if tuple_info.field_len() == 1 => { + let registration = try_get_registration( + *TupleLikeInfo::field_at(tuple_info, 0)?.ty(), + self.registry, + )?; + let value = variant.newtype_variant_seed(TypedReflectDeserializer::new( + registration, + self.registry, + ))?; + let mut dynamic_tuple = DynamicTuple::default(); + dynamic_tuple.insert_boxed(value); + dynamic_tuple.into() + } + VariantInfo::Tuple(tuple_info) => variant + .tuple_variant( + tuple_info.field_len(), + TupleVariantVisitor { + tuple_info, + registration: self.registration, + registry: self.registry, + }, + )? + .into(), + }; + let variant_name = variant_info.name(); + let variant_index = self + .enum_info + .index_of(variant_name) + .expect("variant should exist"); + dynamic_enum.set_variant_with_index(variant_index, variant_name, value); + Ok(dynamic_enum) + } +} + +struct VariantDeserializer { + enum_info: &'static EnumInfo, +} + +impl<'de> DeserializeSeed<'de> for VariantDeserializer { + type Value = &'static VariantInfo; + + fn deserialize(self, deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + struct VariantVisitor(&'static EnumInfo); + + impl<'de> Visitor<'de> for VariantVisitor { + type Value = &'static VariantInfo; + + fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { + formatter.write_str("expected either a variant index or variant name") + } + + fn visit_u32(self, variant_index: u32) -> Result + where + E: Error, + { + self.0.variant_at(variant_index as usize).ok_or_else(|| { + Error::custom(format_args!( + "no variant found at index `{}` on enum `{}`", + variant_index, + self.0.type_path() + )) + }) + } + + fn visit_str(self, variant_name: &str) -> Result + where + E: Error, + { + self.0.variant(variant_name).ok_or_else(|| { + let names = self.0.iter().map(VariantInfo::name); + Error::custom(format_args!( + "unknown variant `{}`, expected one of {:?}", + variant_name, + ExpectedValues::from_iter(names) + )) + }) + } + } + + deserializer.deserialize_identifier(VariantVisitor(self.enum_info)) + } +} + +struct StructVariantVisitor<'a> { + struct_info: &'static StructVariantInfo, + registration: &'a TypeRegistration, + registry: &'a TypeRegistry, +} + +impl<'a, 'de> Visitor<'de> for StructVariantVisitor<'a> { + type Value = DynamicStruct; + + fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { + formatter.write_str("reflected struct variant value") + } + + fn visit_seq(self, mut seq: A) -> Result + where + A: SeqAccess<'de>, + { + visit_struct_seq(&mut seq, self.struct_info, self.registration, self.registry) + } + + fn visit_map(self, mut map: V) -> Result + where + V: MapAccess<'de>, + { + visit_struct(&mut map, self.struct_info, self.registration, self.registry) + } +} + +struct TupleVariantVisitor<'a> { + tuple_info: &'static TupleVariantInfo, + registration: &'a TypeRegistration, + registry: &'a TypeRegistry, +} + +impl<'a, 'de> Visitor<'de> for TupleVariantVisitor<'a> { + type Value = DynamicTuple; + + fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { + formatter.write_str("reflected tuple variant value") + } + + fn visit_seq(self, mut seq: V) -> Result + where + V: SeqAccess<'de>, + { + visit_tuple(&mut seq, self.tuple_info, self.registration, self.registry) + } +} diff --git a/crates/bevy_reflect/src/serde/de/helpers.rs b/crates/bevy_reflect/src/serde/de/helpers.rs new file mode 100644 index 0000000000..3243a6c011 --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/helpers.rs @@ -0,0 +1,70 @@ +use core::fmt::{Debug, Display, Formatter}; +use serde::de::{Error, Visitor}; +use serde::Deserialize; +use std::fmt; + +/// A debug struct used for error messages that displays a list of expected values. +/// +/// # Example +/// +/// ```ignore (Can't import private struct from doctest) +/// let expected = vec!["foo", "bar", "baz"]; +/// assert_eq!("`foo`, `bar`, `baz`", format!("{}", ExpectedValues(expected))); +/// ``` +pub(super) struct ExpectedValues(pub Vec); + +impl FromIterator for ExpectedValues { + fn from_iter>(iter: I) -> Self { + Self(iter.into_iter().collect()) + } +} + +impl Debug for ExpectedValues { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + let len = self.0.len(); + for (index, item) in self.0.iter().enumerate() { + write!(f, "`{item}`")?; + if index < len - 1 { + write!(f, ", ")?; + } + } + Ok(()) + } +} + +/// Represents a simple reflected identifier. +#[derive(Debug, Clone, Eq, PartialEq)] +pub(super) struct Ident(pub String); + +impl<'de> Deserialize<'de> for Ident { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + struct IdentVisitor; + + impl<'de> Visitor<'de> for IdentVisitor { + type Value = Ident; + + fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { + formatter.write_str("identifier") + } + + fn visit_str(self, value: &str) -> Result + where + E: Error, + { + Ok(Ident(value.to_string())) + } + + fn visit_string(self, value: String) -> Result + where + E: Error, + { + Ok(Ident(value)) + } + } + + deserializer.deserialize_identifier(IdentVisitor) + } +} diff --git a/crates/bevy_reflect/src/serde/de/lists.rs b/crates/bevy_reflect/src/serde/de/lists.rs new file mode 100644 index 0000000000..30e7d9282d --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/lists.rs @@ -0,0 +1,45 @@ +use crate::serde::de::registration_utils::try_get_registration; +use crate::serde::TypedReflectDeserializer; +use crate::{DynamicList, ListInfo, TypeRegistry}; +use core::fmt::Formatter; +use serde::de::{SeqAccess, Visitor}; +use std::fmt; + +/// A [`Visitor`] for deserializing [`List`] values. +/// +/// [`List`]: crate::List +pub(super) struct ListVisitor<'a> { + list_info: &'static ListInfo, + registry: &'a TypeRegistry, +} + +impl<'a> ListVisitor<'a> { + pub fn new(list_info: &'static ListInfo, registry: &'a TypeRegistry) -> Self { + Self { + list_info, + registry, + } + } +} + +impl<'a, 'de> Visitor<'de> for ListVisitor<'a> { + type Value = DynamicList; + + fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { + formatter.write_str("reflected list value") + } + + fn visit_seq(self, mut seq: V) -> Result + where + V: SeqAccess<'de>, + { + let mut list = DynamicList::default(); + let registration = try_get_registration(self.list_info.item_ty(), self.registry)?; + while let Some(value) = + seq.next_element_seed(TypedReflectDeserializer::new(registration, self.registry))? + { + list.push_box(value); + } + Ok(list) + } +} diff --git a/crates/bevy_reflect/src/serde/de/maps.rs b/crates/bevy_reflect/src/serde/de/maps.rs new file mode 100644 index 0000000000..0b185110d6 --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/maps.rs @@ -0,0 +1,49 @@ +use crate::serde::de::registration_utils::try_get_registration; +use crate::serde::TypedReflectDeserializer; +use crate::{DynamicMap, Map, MapInfo, TypeRegistry}; +use core::fmt::Formatter; +use serde::de::{MapAccess, Visitor}; +use std::fmt; + +/// A [`Visitor`] for deserializing [`Map`] values. +/// +/// [`Map`]: crate::Map +pub(super) struct MapVisitor<'a> { + map_info: &'static MapInfo, + registry: &'a TypeRegistry, +} + +impl<'a> MapVisitor<'a> { + pub fn new(map_info: &'static MapInfo, registry: &'a TypeRegistry) -> Self { + Self { map_info, registry } + } +} + +impl<'a, 'de> Visitor<'de> for MapVisitor<'a> { + type Value = DynamicMap; + + fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { + formatter.write_str("reflected map value") + } + + fn visit_map(self, mut map: V) -> Result + where + V: MapAccess<'de>, + { + let mut dynamic_map = DynamicMap::default(); + let key_registration = try_get_registration(self.map_info.key_ty(), self.registry)?; + let value_registration = try_get_registration(self.map_info.value_ty(), self.registry)?; + while let Some(key) = map.next_key_seed(TypedReflectDeserializer::new( + key_registration, + self.registry, + ))? { + let value = map.next_value_seed(TypedReflectDeserializer::new( + value_registration, + self.registry, + ))?; + dynamic_map.insert_boxed(key, value); + } + + Ok(dynamic_map) + } +} diff --git a/crates/bevy_reflect/src/serde/de/mod.rs b/crates/bevy_reflect/src/serde/de/mod.rs new file mode 100644 index 0000000000..40bf927774 --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/mod.rs @@ -0,0 +1,515 @@ +pub use deserializer::*; +pub use registrations::*; + +mod arrays; +mod deserializer; +mod enums; +mod helpers; +mod lists; +mod maps; +mod options; +mod registration_utils; +mod registrations; +mod sets; +mod struct_utils; +mod structs; +mod tuple_structs; +mod tuple_utils; +mod tuples; + +#[cfg(test)] +mod tests { + use bincode::Options; + use std::any::TypeId; + use std::f32::consts::PI; + use std::ops::RangeInclusive; + + use serde::de::DeserializeSeed; + use serde::Deserialize; + + use bevy_utils::{HashMap, HashSet}; + + use crate as bevy_reflect; + use crate::serde::{ReflectDeserializer, ReflectSerializer, TypedReflectDeserializer}; + use crate::{ + DynamicEnum, FromReflect, PartialReflect, Reflect, ReflectDeserialize, TypeRegistry, + }; + + #[derive(Reflect, Debug, PartialEq)] + struct MyStruct { + primitive_value: i8, + option_value: Option, + option_value_complex: Option, + tuple_value: (f32, usize), + list_value: Vec, + array_value: [i32; 5], + map_value: HashMap, + set_value: HashSet, + struct_value: SomeStruct, + tuple_struct_value: SomeTupleStruct, + unit_struct: SomeUnitStruct, + unit_enum: SomeEnum, + newtype_enum: SomeEnum, + tuple_enum: SomeEnum, + struct_enum: SomeEnum, + ignored_struct: SomeIgnoredStruct, + ignored_tuple_struct: SomeIgnoredTupleStruct, + ignored_struct_variant: SomeIgnoredEnum, + ignored_tuple_variant: SomeIgnoredEnum, + custom_deserialize: CustomDeserialize, + } + + #[derive(Reflect, Debug, PartialEq)] + struct SomeStruct { + foo: i64, + } + + #[derive(Reflect, Debug, PartialEq)] + struct SomeTupleStruct(String); + + #[derive(Reflect, Debug, PartialEq)] + struct SomeUnitStruct; + + #[derive(Reflect, Debug, PartialEq)] + struct SomeIgnoredStruct { + #[reflect(ignore)] + ignored: i32, + } + + #[derive(Reflect, Debug, PartialEq)] + struct SomeIgnoredTupleStruct(#[reflect(ignore)] i32); + + #[derive(Reflect, Debug, PartialEq, Deserialize)] + struct SomeDeserializableStruct { + foo: i64, + } + + /// Implements a custom deserialize using `#[reflect(Deserialize)]`. + /// + /// For testing purposes, this is just the auto-generated one from deriving. + #[derive(Reflect, Debug, PartialEq, Deserialize)] + #[reflect(Deserialize)] + struct CustomDeserialize { + value: usize, + #[serde(alias = "renamed")] + inner_struct: SomeDeserializableStruct, + } + + #[derive(Reflect, Debug, PartialEq)] + enum SomeEnum { + Unit, + NewType(usize), + Tuple(f32, f32), + Struct { foo: String }, + } + + #[derive(Reflect, Debug, PartialEq)] + enum SomeIgnoredEnum { + Tuple(#[reflect(ignore)] f32, #[reflect(ignore)] f32), + Struct { + #[reflect(ignore)] + foo: String, + }, + } + + fn get_registry() -> TypeRegistry { + let mut registry = TypeRegistry::default(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::<(f32, usize)>(); + registry.register::<[i32; 5]>(); + registry.register::>(); + registry.register::>(); + registry.register::>(); + registry.register::>(); + registry.register::>(); + registry.register_type_data::, ReflectDeserialize>(); + registry + } + + fn get_my_struct() -> MyStruct { + let mut map = HashMap::new(); + map.insert(64, 32); + + let mut set = HashSet::new(); + set.insert(64); + + MyStruct { + primitive_value: 123, + option_value: Some(String::from("Hello world!")), + option_value_complex: Some(SomeStruct { foo: 123 }), + tuple_value: (PI, 1337), + list_value: vec![-2, -1, 0, 1, 2], + array_value: [-2, -1, 0, 1, 2], + map_value: map, + set_value: set, + struct_value: SomeStruct { foo: 999999999 }, + tuple_struct_value: SomeTupleStruct(String::from("Tuple Struct")), + unit_struct: SomeUnitStruct, + unit_enum: SomeEnum::Unit, + newtype_enum: SomeEnum::NewType(123), + tuple_enum: SomeEnum::Tuple(1.23, 3.21), + struct_enum: SomeEnum::Struct { + foo: String::from("Struct variant value"), + }, + ignored_struct: SomeIgnoredStruct { ignored: 0 }, + ignored_tuple_struct: SomeIgnoredTupleStruct(0), + ignored_struct_variant: SomeIgnoredEnum::Struct { + foo: String::default(), + }, + ignored_tuple_variant: SomeIgnoredEnum::Tuple(0.0, 0.0), + custom_deserialize: CustomDeserialize { + value: 100, + inner_struct: SomeDeserializableStruct { foo: 101 }, + }, + } + } + + #[test] + fn should_deserialize() { + let expected = get_my_struct(); + let registry = get_registry(); + + let input = r#"{ + "bevy_reflect::serde::de::tests::MyStruct": ( + primitive_value: 123, + option_value: Some("Hello world!"), + option_value_complex: Some(( + foo: 123, + )), + tuple_value: (3.1415927, 1337), + list_value: [ + -2, + -1, + 0, + 1, + 2, + ], + array_value: (-2, -1, 0, 1, 2), + map_value: { + 64: 32, + }, + set_value: [ + 64, + ], + struct_value: ( + foo: 999999999, + ), + tuple_struct_value: ("Tuple Struct"), + unit_struct: (), + unit_enum: Unit, + newtype_enum: NewType(123), + tuple_enum: Tuple(1.23, 3.21), + struct_enum: Struct( + foo: "Struct variant value", + ), + ignored_struct: (), + ignored_tuple_struct: (), + ignored_struct_variant: Struct(), + ignored_tuple_variant: Tuple(), + custom_deserialize: ( + value: 100, + renamed: ( + foo: 101, + ), + ), + ), + }"#; + + let reflect_deserializer = ReflectDeserializer::new(®istry); + let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap(); + let dynamic_output = reflect_deserializer + .deserialize(&mut ron_deserializer) + .unwrap(); + + let output = ::from_reflect(dynamic_output.as_ref()).unwrap(); + assert_eq!(expected, output); + } + + #[test] + fn should_deserialize_value() { + let input = r#"{ + "f32": 1.23, + }"#; + + let registry = get_registry(); + let reflect_deserializer = ReflectDeserializer::new(®istry); + let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap(); + let dynamic_output = reflect_deserializer + .deserialize(&mut ron_deserializer) + .unwrap(); + let output = dynamic_output + .try_take::() + .expect("underlying type should be f32"); + assert_eq!(1.23, output); + } + + #[test] + fn should_deserialized_typed() { + #[derive(Reflect, Debug, PartialEq)] + struct Foo { + bar: i32, + } + + let expected = Foo { bar: 123 }; + + let input = r#"( + bar: 123 + )"#; + + let mut registry = get_registry(); + registry.register::(); + let registration = registry.get(TypeId::of::()).unwrap(); + let reflect_deserializer = TypedReflectDeserializer::new(registration, ®istry); + let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap(); + let dynamic_output = reflect_deserializer + .deserialize(&mut ron_deserializer) + .unwrap(); + + let output = + ::from_reflect(dynamic_output.as_ref().as_partial_reflect()) + .unwrap(); + assert_eq!(expected, output); + } + + #[test] + fn should_deserialize_option() { + #[derive(Reflect, Debug, PartialEq)] + struct OptionTest { + none: Option<()>, + simple: Option, + complex: Option, + } + + let expected = OptionTest { + none: None, + simple: Some(String::from("Hello world!")), + complex: Some(SomeStruct { foo: 123 }), + }; + + let mut registry = get_registry(); + registry.register::(); + registry.register::>(); + + // === Normal === // + let input = r#"{ + "bevy_reflect::serde::de::tests::OptionTest": ( + none: None, + simple: Some("Hello world!"), + complex: Some(( + foo: 123, + )), + ), + }"#; + + let reflect_deserializer = ReflectDeserializer::new(®istry); + let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap(); + let dynamic_output = reflect_deserializer + .deserialize(&mut ron_deserializer) + .unwrap(); + + let output = ::from_reflect(dynamic_output.as_ref()).unwrap(); + assert_eq!(expected, output, "failed to deserialize Options"); + + // === Implicit Some === // + let input = r#" + #![enable(implicit_some)] + { + "bevy_reflect::serde::de::tests::OptionTest": ( + none: None, + simple: "Hello world!", + complex: ( + foo: 123, + ), + ), + }"#; + + let reflect_deserializer = ReflectDeserializer::new(®istry); + let mut ron_deserializer = ron::de::Deserializer::from_str(input).unwrap(); + let dynamic_output = reflect_deserializer + .deserialize(&mut ron_deserializer) + .unwrap(); + + let output = ::from_reflect(dynamic_output.as_ref()).unwrap(); + assert_eq!( + expected, output, + "failed to deserialize Options with implicit Some" + ); + } + + #[test] + fn enum_should_deserialize() { + #[derive(Reflect)] + enum MyEnum { + Unit, + NewType(usize), + Tuple(f32, f32), + Struct { value: String }, + } + + let mut registry = get_registry(); + registry.register::(); + + // === Unit Variant === // + let input = r#"{ + "bevy_reflect::serde::de::tests::MyEnum": Unit, +}"#; + let reflect_deserializer = ReflectDeserializer::new(®istry); + let mut deserializer = ron::de::Deserializer::from_str(input).unwrap(); + let output = reflect_deserializer.deserialize(&mut deserializer).unwrap(); + + let expected = DynamicEnum::from(MyEnum::Unit); + assert!(expected.reflect_partial_eq(output.as_ref()).unwrap()); + + // === NewType Variant === // + let input = r#"{ + "bevy_reflect::serde::de::tests::MyEnum": NewType(123), +}"#; + let reflect_deserializer = ReflectDeserializer::new(®istry); + let mut deserializer = ron::de::Deserializer::from_str(input).unwrap(); + let output = reflect_deserializer.deserialize(&mut deserializer).unwrap(); + + let expected = DynamicEnum::from(MyEnum::NewType(123)); + assert!(expected.reflect_partial_eq(output.as_ref()).unwrap()); + + // === Tuple Variant === // + let input = r#"{ + "bevy_reflect::serde::de::tests::MyEnum": Tuple(1.23, 3.21), +}"#; + let reflect_deserializer = ReflectDeserializer::new(®istry); + let mut deserializer = ron::de::Deserializer::from_str(input).unwrap(); + let output = reflect_deserializer.deserialize(&mut deserializer).unwrap(); + + let expected = DynamicEnum::from(MyEnum::Tuple(1.23, 3.21)); + assert!(expected + .reflect_partial_eq(output.as_partial_reflect()) + .unwrap()); + + // === Struct Variant === // + let input = r#"{ + "bevy_reflect::serde::de::tests::MyEnum": Struct( + value: "I <3 Enums", + ), +}"#; + let reflect_deserializer = ReflectDeserializer::new(®istry); + let mut deserializer = ron::de::Deserializer::from_str(input).unwrap(); + let output = reflect_deserializer.deserialize(&mut deserializer).unwrap(); + + let expected = DynamicEnum::from(MyEnum::Struct { + value: String::from("I <3 Enums"), + }); + assert!(expected + .reflect_partial_eq(output.as_partial_reflect()) + .unwrap()); + } + + // Regression test for https://github.com/bevyengine/bevy/issues/12462 + #[test] + fn should_reserialize() { + let registry = get_registry(); + let input1 = get_my_struct(); + + let serializer1 = ReflectSerializer::new(&input1, ®istry); + let serialized1 = ron::ser::to_string(&serializer1).unwrap(); + + let mut deserializer = ron::de::Deserializer::from_str(&serialized1).unwrap(); + let reflect_deserializer = ReflectDeserializer::new(®istry); + let input2 = reflect_deserializer.deserialize(&mut deserializer).unwrap(); + + let serializer2 = ReflectSerializer::new(input2.as_partial_reflect(), ®istry); + let serialized2 = ron::ser::to_string(&serializer2).unwrap(); + + assert_eq!(serialized1, serialized2); + } + + #[test] + fn should_deserialize_non_self_describing_binary() { + let expected = get_my_struct(); + let registry = get_registry(); + + let input = vec![ + 1, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 98, 101, 118, 121, 95, 114, 101, 102, + 108, 101, 99, 116, 58, 58, 115, 101, 114, 100, 101, 58, 58, 100, 101, 58, 58, 116, 101, + 115, 116, 115, 58, 58, 77, 121, 83, 116, 114, 117, 99, 116, 123, 1, 12, 0, 0, 0, 0, 0, + 0, 0, 72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33, 1, 123, 0, 0, 0, 0, 0, + 0, 0, 219, 15, 73, 64, 57, 5, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 254, 255, 255, + 255, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 254, 255, 255, 255, 255, + 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 32, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 255, 201, 154, 59, 0, 0, 0, 0, 12, 0, 0, + 0, 0, 0, 0, 0, 84, 117, 112, 108, 101, 32, 83, 116, 114, 117, 99, 116, 0, 0, 0, 0, 1, + 0, 0, 0, 123, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 164, 112, 157, 63, 164, 112, 77, 64, 3, + 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 83, 116, 114, 117, 99, 116, 32, 118, 97, 114, 105, + 97, 110, 116, 32, 118, 97, 108, 117, 101, 1, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, + 0, 0, 101, 0, 0, 0, 0, 0, 0, 0, + ]; + + let deserializer = ReflectDeserializer::new(®istry); + + let dynamic_output = bincode::DefaultOptions::new() + .with_fixint_encoding() + .deserialize_seed(deserializer, &input) + .unwrap(); + + let output = ::from_reflect(dynamic_output.as_ref()).unwrap(); + assert_eq!(expected, output); + } + + #[test] + fn should_deserialize_self_describing_binary() { + let expected = get_my_struct(); + let registry = get_registry(); + + let input = vec![ + 129, 217, 40, 98, 101, 118, 121, 95, 114, 101, 102, 108, 101, 99, 116, 58, 58, 115, + 101, 114, 100, 101, 58, 58, 100, 101, 58, 58, 116, 101, 115, 116, 115, 58, 58, 77, 121, + 83, 116, 114, 117, 99, 116, 220, 0, 20, 123, 172, 72, 101, 108, 108, 111, 32, 119, 111, + 114, 108, 100, 33, 145, 123, 146, 202, 64, 73, 15, 219, 205, 5, 57, 149, 254, 255, 0, + 1, 2, 149, 254, 255, 0, 1, 2, 129, 64, 32, 145, 64, 145, 206, 59, 154, 201, 255, 145, + 172, 84, 117, 112, 108, 101, 32, 83, 116, 114, 117, 99, 116, 144, 164, 85, 110, 105, + 116, 129, 167, 78, 101, 119, 84, 121, 112, 101, 123, 129, 165, 84, 117, 112, 108, 101, + 146, 202, 63, 157, 112, 164, 202, 64, 77, 112, 164, 129, 166, 83, 116, 114, 117, 99, + 116, 145, 180, 83, 116, 114, 117, 99, 116, 32, 118, 97, 114, 105, 97, 110, 116, 32, + 118, 97, 108, 117, 101, 144, 144, 129, 166, 83, 116, 114, 117, 99, 116, 144, 129, 165, + 84, 117, 112, 108, 101, 144, 146, 100, 145, 101, + ]; + + let mut reader = std::io::BufReader::new(input.as_slice()); + + let deserializer = ReflectDeserializer::new(®istry); + let dynamic_output = deserializer + .deserialize(&mut rmp_serde::Deserializer::new(&mut reader)) + .unwrap(); + + let output = ::from_reflect(dynamic_output.as_ref()).unwrap(); + assert_eq!(expected, output); + } + + #[test] + fn should_return_error_if_missing_type_data() { + let mut registry = TypeRegistry::new(); + registry.register::>(); + + let input = r#"{"core::ops::RangeInclusive":(start:0.0,end:1.0)}"#; + let mut deserializer = ron::de::Deserializer::from_str(input).unwrap(); + let reflect_deserializer = ReflectDeserializer::new(®istry); + let error = reflect_deserializer + .deserialize(&mut deserializer) + .unwrap_err(); + assert_eq!(error, ron::Error::Message("Type `core::ops::RangeInclusive` did not register the `ReflectDeserialize` type data. For certain types, this may need to be registered manually using `register_type_data`".to_string())); + } +} diff --git a/crates/bevy_reflect/src/serde/de/options.rs b/crates/bevy_reflect/src/serde/de/options.rs new file mode 100644 index 0000000000..103121a4b1 --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/options.rs @@ -0,0 +1,62 @@ +use crate::serde::de::registration_utils::try_get_registration; +use crate::serde::TypedReflectDeserializer; +use crate::{DynamicEnum, DynamicTuple, EnumInfo, TypeRegistry, VariantInfo}; +use core::fmt::Formatter; +use serde::de::{DeserializeSeed, Error, Visitor}; +use std::fmt; + +/// A [`Visitor`] for deserializing [`Option`] values. +pub(super) struct OptionVisitor<'a> { + enum_info: &'static EnumInfo, + registry: &'a TypeRegistry, +} + +impl<'a> OptionVisitor<'a> { + pub fn new(enum_info: &'static EnumInfo, registry: &'a TypeRegistry) -> Self { + Self { + enum_info, + registry, + } + } +} + +impl<'a, 'de> Visitor<'de> for OptionVisitor<'a> { + type Value = DynamicEnum; + + fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { + formatter.write_str("reflected option value of type ")?; + formatter.write_str(self.enum_info.type_path()) + } + + fn visit_none(self) -> Result + where + E: Error, + { + let mut option = DynamicEnum::default(); + option.set_variant("None", ()); + Ok(option) + } + + fn visit_some(self, deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let variant_info = self.enum_info.variant("Some").unwrap(); + match variant_info { + VariantInfo::Tuple(tuple_info) if tuple_info.field_len() == 1 => { + let field = tuple_info.field_at(0).unwrap(); + let registration = try_get_registration(*field.ty(), self.registry)?; + let de = TypedReflectDeserializer::new(registration, self.registry); + let mut value = DynamicTuple::default(); + value.insert_boxed(de.deserialize(deserializer)?); + let mut option = DynamicEnum::default(); + option.set_variant("Some", value); + Ok(option) + } + info => Err(Error::custom(format_args!( + "invalid variant, expected `Some` but got `{}`", + info.name() + ))), + } + } +} diff --git a/crates/bevy_reflect/src/serde/de/registration_utils.rs b/crates/bevy_reflect/src/serde/de/registration_utils.rs new file mode 100644 index 0000000000..8a170d1732 --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/registration_utils.rs @@ -0,0 +1,15 @@ +use crate::{Type, TypeRegistration, TypeRegistry}; +use serde::de::Error; + +/// Attempts to find the [`TypeRegistration`] for a given [type]. +/// +/// [type]: Type +pub(super) fn try_get_registration( + ty: Type, + registry: &TypeRegistry, +) -> Result<&TypeRegistration, E> { + let registration = registry + .get(ty.id()) + .ok_or_else(|| Error::custom(format_args!("no registration found for type `{ty:?}`")))?; + Ok(registration) +} diff --git a/crates/bevy_reflect/src/serde/de/registrations.rs b/crates/bevy_reflect/src/serde/de/registrations.rs new file mode 100644 index 0000000000..9ed10628f7 --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/registrations.rs @@ -0,0 +1,52 @@ +use crate::{TypeRegistration, TypeRegistry}; +use core::fmt::Formatter; +use serde::de::{DeserializeSeed, Error, Visitor}; +use std::fmt; + +/// A deserializer for type registrations. +/// +/// This will return a [`&TypeRegistration`] corresponding to the given type. +/// This deserializer expects a string containing the _full_ [type path] of the +/// type to find the `TypeRegistration` of. +/// +/// [`&TypeRegistration`]: TypeRegistration +/// [type path]: crate::TypePath::type_path +pub struct TypeRegistrationDeserializer<'a> { + registry: &'a TypeRegistry, +} + +impl<'a> TypeRegistrationDeserializer<'a> { + pub fn new(registry: &'a TypeRegistry) -> Self { + Self { registry } + } +} + +impl<'a, 'de> DeserializeSeed<'de> for TypeRegistrationDeserializer<'a> { + type Value = &'a TypeRegistration; + + fn deserialize(self, deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + struct TypeRegistrationVisitor<'a>(&'a TypeRegistry); + + impl<'de, 'a> Visitor<'de> for TypeRegistrationVisitor<'a> { + type Value = &'a TypeRegistration; + + fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { + formatter.write_str("string containing `type` entry for the reflected value") + } + + fn visit_str(self, type_path: &str) -> Result + where + E: Error, + { + self.0.get_with_type_path(type_path).ok_or_else(|| { + Error::custom(format_args!("No registration found for `{type_path}`")) + }) + } + } + + deserializer.deserialize_str(TypeRegistrationVisitor(self.registry)) + } +} diff --git a/crates/bevy_reflect/src/serde/de/sets.rs b/crates/bevy_reflect/src/serde/de/sets.rs new file mode 100644 index 0000000000..fcb72a8f77 --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/sets.rs @@ -0,0 +1,44 @@ +use crate::serde::de::registration_utils::try_get_registration; +use crate::serde::TypedReflectDeserializer; +use crate::{DynamicSet, Set, SetInfo, TypeRegistry}; +use core::fmt::Formatter; +use serde::de::{SeqAccess, Visitor}; +use std::fmt; + +/// A [`Visitor`] for deserializing [`Set`] values. +/// +/// [`Set`]: crate::Set +pub(super) struct SetVisitor<'a> { + set_info: &'static SetInfo, + registry: &'a TypeRegistry, +} + +impl<'a> SetVisitor<'a> { + pub fn new(set_info: &'static SetInfo, registry: &'a TypeRegistry) -> Self { + Self { set_info, registry } + } +} + +impl<'a, 'de> Visitor<'de> for SetVisitor<'a> { + type Value = DynamicSet; + + fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { + formatter.write_str("reflected set value") + } + + fn visit_seq(self, mut set: V) -> Result + where + V: SeqAccess<'de>, + { + let mut dynamic_set = DynamicSet::default(); + let value_registration = try_get_registration(self.set_info.value_ty(), self.registry)?; + while let Some(value) = set.next_element_seed(TypedReflectDeserializer::new( + value_registration, + self.registry, + ))? { + dynamic_set.insert_boxed(value); + } + + Ok(dynamic_set) + } +} diff --git a/crates/bevy_reflect/src/serde/de/struct_utils.rs b/crates/bevy_reflect/src/serde/de/struct_utils.rs new file mode 100644 index 0000000000..5035746a60 --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/struct_utils.rs @@ -0,0 +1,168 @@ +use crate::serde::de::helpers::{ExpectedValues, Ident}; +use crate::serde::de::registration_utils::try_get_registration; +use crate::serde::{SerializationData, TypedReflectDeserializer}; +use crate::{ + DynamicStruct, NamedField, StructInfo, StructVariantInfo, TypeRegistration, TypeRegistry, +}; +use core::slice::Iter; +use serde::de::{Error, MapAccess, SeqAccess}; + +/// A helper trait for accessing type information from struct-like types. +pub(super) trait StructLikeInfo { + fn field(&self, name: &str) -> Result<&NamedField, E>; + fn field_at(&self, index: usize) -> Result<&NamedField, E>; + fn field_len(&self) -> usize; + fn iter_fields(&self) -> Iter<'_, NamedField>; +} + +impl StructLikeInfo for StructInfo { + fn field(&self, name: &str) -> Result<&NamedField, E> { + Self::field(self, name).ok_or_else(|| { + Error::custom(format_args!( + "no field named {} on struct {}", + name, + self.type_path(), + )) + }) + } + + fn field_at(&self, index: usize) -> Result<&NamedField, E> { + Self::field_at(self, index).ok_or_else(|| { + Error::custom(format_args!( + "no field at index {} on struct {}", + index, + self.type_path(), + )) + }) + } + + fn field_len(&self) -> usize { + Self::field_len(self) + } + + fn iter_fields(&self) -> Iter<'_, NamedField> { + self.iter() + } +} + +impl StructLikeInfo for StructVariantInfo { + fn field(&self, name: &str) -> Result<&NamedField, E> { + Self::field(self, name).ok_or_else(|| { + Error::custom(format_args!( + "no field named {} on variant {}", + name, + self.name(), + )) + }) + } + + fn field_at(&self, index: usize) -> Result<&NamedField, E> { + Self::field_at(self, index).ok_or_else(|| { + Error::custom(format_args!( + "no field at index {} on variant {}", + index, + self.name(), + )) + }) + } + + fn field_len(&self) -> usize { + Self::field_len(self) + } + + fn iter_fields(&self) -> Iter<'_, NamedField> { + self.iter() + } +} + +/// Deserializes a [struct-like] type from a mapping of fields, returning a [`DynamicStruct`]. +/// +/// [struct-like]: StructLikeInfo +pub(super) fn visit_struct<'de, T, V>( + map: &mut V, + info: &'static T, + registration: &TypeRegistration, + registry: &TypeRegistry, +) -> Result +where + T: StructLikeInfo, + V: MapAccess<'de>, +{ + let mut dynamic_struct = DynamicStruct::default(); + while let Some(Ident(key)) = map.next_key::()? { + let field = info.field::(&key).map_err(|_| { + let fields = info.iter_fields().map(NamedField::name); + Error::custom(format_args!( + "unknown field `{}`, expected one of {:?}", + key, + ExpectedValues::from_iter(fields) + )) + })?; + let registration = try_get_registration(*field.ty(), registry)?; + let value = map.next_value_seed(TypedReflectDeserializer::new(registration, registry))?; + dynamic_struct.insert_boxed(&key, value); + } + + if let Some(serialization_data) = registration.data::() { + for (skipped_index, skipped_field) in serialization_data.iter_skipped() { + let Ok(field) = info.field_at::(*skipped_index) else { + continue; + }; + dynamic_struct.insert_boxed( + field.name(), + skipped_field.generate_default().into_partial_reflect(), + ); + } + } + + Ok(dynamic_struct) +} + +/// Deserializes a [struct-like] type from a sequence of fields, returning a [`DynamicStruct`]. +/// +/// [struct-like]: StructLikeInfo +pub(super) fn visit_struct_seq<'de, T, V>( + seq: &mut V, + info: &T, + registration: &TypeRegistration, + registry: &TypeRegistry, +) -> Result +where + T: StructLikeInfo, + V: SeqAccess<'de>, +{ + let mut dynamic_struct = DynamicStruct::default(); + + let len = info.field_len(); + + if len == 0 { + // Handle unit structs + return Ok(dynamic_struct); + } + + let serialization_data = registration.data::(); + + for index in 0..len { + let name = info.field_at::(index)?.name(); + + if serialization_data + .map(|data| data.is_field_skipped(index)) + .unwrap_or_default() + { + if let Some(value) = serialization_data.unwrap().generate_default(index) { + dynamic_struct.insert_boxed(name, value.into_partial_reflect()); + } + continue; + } + + let value = seq + .next_element_seed(TypedReflectDeserializer::new( + try_get_registration(*info.field_at(index)?.ty(), registry)?, + registry, + ))? + .ok_or_else(|| Error::invalid_length(index, &len.to_string().as_str()))?; + dynamic_struct.insert_boxed(name, value); + } + + Ok(dynamic_struct) +} diff --git a/crates/bevy_reflect/src/serde/de/structs.rs b/crates/bevy_reflect/src/serde/de/structs.rs new file mode 100644 index 0000000000..85aa6f15b3 --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/structs.rs @@ -0,0 +1,50 @@ +use crate::serde::de::struct_utils::{visit_struct, visit_struct_seq}; +use crate::{DynamicStruct, StructInfo, TypeRegistration, TypeRegistry}; +use core::fmt::Formatter; +use serde::de::{MapAccess, SeqAccess, Visitor}; +use std::fmt; + +/// A [`Visitor`] for deserializing [`Struct`] values. +/// +/// [`Struct`]: crate::Struct +pub(super) struct StructVisitor<'a> { + struct_info: &'static StructInfo, + registration: &'a TypeRegistration, + registry: &'a TypeRegistry, +} + +impl<'a> StructVisitor<'a> { + pub fn new( + struct_info: &'static StructInfo, + registration: &'a TypeRegistration, + registry: &'a TypeRegistry, + ) -> Self { + Self { + struct_info, + registration, + registry, + } + } +} + +impl<'a, 'de> Visitor<'de> for StructVisitor<'a> { + type Value = DynamicStruct; + + fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { + formatter.write_str("reflected struct value") + } + + fn visit_seq(self, mut seq: A) -> Result + where + A: SeqAccess<'de>, + { + visit_struct_seq(&mut seq, self.struct_info, self.registration, self.registry) + } + + fn visit_map(self, mut map: V) -> Result + where + V: MapAccess<'de>, + { + visit_struct(&mut map, self.struct_info, self.registration, self.registry) + } +} diff --git a/crates/bevy_reflect/src/serde/de/tuple_structs.rs b/crates/bevy_reflect/src/serde/de/tuple_structs.rs new file mode 100644 index 0000000000..8bbe44a324 --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/tuple_structs.rs @@ -0,0 +1,49 @@ +use crate::serde::de::tuple_utils::visit_tuple; +use crate::{DynamicTupleStruct, TupleStructInfo, TypeRegistration, TypeRegistry}; +use core::fmt::Formatter; +use serde::de::{SeqAccess, Visitor}; +use std::fmt; + +/// A [`Visitor`] for deserializing [`TupleStruct`] values. +/// +/// [`TupleStruct`]: crate::TupleStruct +pub(super) struct TupleStructVisitor<'a> { + tuple_struct_info: &'static TupleStructInfo, + registration: &'a TypeRegistration, + registry: &'a TypeRegistry, +} + +impl<'a> TupleStructVisitor<'a> { + pub fn new( + tuple_struct_info: &'static TupleStructInfo, + registration: &'a TypeRegistration, + registry: &'a TypeRegistry, + ) -> Self { + Self { + tuple_struct_info, + registration, + registry, + } + } +} + +impl<'a, 'de> Visitor<'de> for TupleStructVisitor<'a> { + type Value = DynamicTupleStruct; + + fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { + formatter.write_str("reflected tuple struct value") + } + + fn visit_seq(self, mut seq: V) -> Result + where + V: SeqAccess<'de>, + { + visit_tuple( + &mut seq, + self.tuple_struct_info, + self.registration, + self.registry, + ) + .map(DynamicTupleStruct::from) + } +} diff --git a/crates/bevy_reflect/src/serde/de/tuple_utils.rs b/crates/bevy_reflect/src/serde/de/tuple_utils.rs new file mode 100644 index 0000000000..542b096bf5 --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/tuple_utils.rs @@ -0,0 +1,102 @@ +use crate::serde::de::registration_utils::try_get_registration; +use crate::serde::{SerializationData, TypedReflectDeserializer}; +use crate::{ + DynamicTuple, TupleInfo, TupleStructInfo, TupleVariantInfo, TypeRegistration, TypeRegistry, + UnnamedField, +}; +use serde::de::{Error, SeqAccess}; + +pub(super) trait TupleLikeInfo { + fn field_at(&self, index: usize) -> Result<&UnnamedField, E>; + fn field_len(&self) -> usize; +} + +impl TupleLikeInfo for TupleInfo { + fn field_len(&self) -> usize { + Self::field_len(self) + } + + fn field_at(&self, index: usize) -> Result<&UnnamedField, E> { + Self::field_at(self, index).ok_or_else(|| { + Error::custom(format_args!( + "no field at index {} on tuple {}", + index, + self.type_path(), + )) + }) + } +} + +impl TupleLikeInfo for TupleStructInfo { + fn field_len(&self) -> usize { + Self::field_len(self) + } + + fn field_at(&self, index: usize) -> Result<&UnnamedField, E> { + Self::field_at(self, index).ok_or_else(|| { + Error::custom(format_args!( + "no field at index {} on tuple struct {}", + index, + self.type_path(), + )) + }) + } +} + +impl TupleLikeInfo for TupleVariantInfo { + fn field_len(&self) -> usize { + Self::field_len(self) + } + + fn field_at(&self, index: usize) -> Result<&UnnamedField, E> { + Self::field_at(self, index).ok_or_else(|| { + Error::custom(format_args!( + "no field at index {} on tuple variant {}", + index, + self.name(), + )) + }) + } +} + +/// Deserializes a [tuple-like] type from a sequence of elements, returning a [`DynamicTuple`]. +/// +/// [tuple-like]: TupleLikeInfo +pub(super) fn visit_tuple<'de, T, V>( + seq: &mut V, + info: &T, + registration: &TypeRegistration, + registry: &TypeRegistry, +) -> Result +where + T: TupleLikeInfo, + V: SeqAccess<'de>, +{ + let mut tuple = DynamicTuple::default(); + + let len = info.field_len(); + + if len == 0 { + // Handle empty tuple/tuple struct + return Ok(tuple); + } + + let serialization_data = registration.data::(); + + for index in 0..len { + if let Some(value) = serialization_data.and_then(|data| data.generate_default(index)) { + tuple.insert_boxed(value.into_partial_reflect()); + continue; + } + + let value = seq + .next_element_seed(TypedReflectDeserializer::new( + try_get_registration(*info.field_at(index)?.ty(), registry)?, + registry, + ))? + .ok_or_else(|| Error::invalid_length(index, &len.to_string().as_str()))?; + tuple.insert_boxed(value); + } + + Ok(tuple) +} diff --git a/crates/bevy_reflect/src/serde/de/tuples.rs b/crates/bevy_reflect/src/serde/de/tuples.rs new file mode 100644 index 0000000000..de18cbda61 --- /dev/null +++ b/crates/bevy_reflect/src/serde/de/tuples.rs @@ -0,0 +1,43 @@ +use crate::serde::de::tuple_utils::visit_tuple; +use crate::{DynamicTuple, TupleInfo, TypeRegistration, TypeRegistry}; +use core::fmt::Formatter; +use serde::de::{SeqAccess, Visitor}; +use std::fmt; + +/// A [`Visitor`] for deserializing [`Tuple`] values. +/// +/// [`Tuple`]: crate::Tuple +pub(super) struct TupleVisitor<'a> { + tuple_info: &'static TupleInfo, + registration: &'a TypeRegistration, + registry: &'a TypeRegistry, +} + +impl<'a> TupleVisitor<'a> { + pub fn new( + tuple_info: &'static TupleInfo, + registration: &'a TypeRegistration, + registry: &'a TypeRegistry, + ) -> Self { + Self { + tuple_info, + registration, + registry, + } + } +} + +impl<'a, 'de> Visitor<'de> for TupleVisitor<'a> { + type Value = DynamicTuple; + + fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { + formatter.write_str("reflected tuple value") + } + + fn visit_seq(self, mut seq: V) -> Result + where + V: SeqAccess<'de>, + { + visit_tuple(&mut seq, self.tuple_info, self.registration, self.registry) + } +} diff --git a/crates/bevy_reflect/src/serde/ser.rs b/crates/bevy_reflect/src/serde/ser.rs deleted file mode 100644 index 8615171238..0000000000 --- a/crates/bevy_reflect/src/serde/ser.rs +++ /dev/null @@ -1,1012 +0,0 @@ -use crate::{ - Array, Enum, List, Map, PartialReflect, ReflectRef, ReflectSerialize, Set, Struct, Tuple, - TupleStruct, TypeInfo, TypeRegistry, VariantInfo, VariantType, -}; -use serde::ser::{ - Error, SerializeStruct, SerializeStructVariant, SerializeTuple, SerializeTupleStruct, - SerializeTupleVariant, -}; -use serde::{ - ser::{SerializeMap, SerializeSeq}, - Serialize, -}; - -use super::SerializationData; - -pub enum Serializable<'a> { - Owned(Box), - Borrowed(&'a dyn erased_serde::Serialize), -} - -impl<'a> Serializable<'a> { - #[allow(clippy::should_implement_trait)] - pub fn borrow(&self) -> &dyn erased_serde::Serialize { - match self { - Serializable::Borrowed(serialize) => serialize, - Serializable::Owned(serialize) => serialize, - } - } -} - -fn get_serializable<'a, E: Error>( - reflect_value: &'a dyn PartialReflect, - type_registry: &TypeRegistry, -) -> Result, E> { - let Some(reflect_value) = reflect_value.try_as_reflect() else { - return Err(Error::custom(format_args!( - "Type '{}' does not implement `Reflect`", - reflect_value.reflect_type_path() - ))); - }; - let info = reflect_value.get_represented_type_info().ok_or_else(|| { - Error::custom(format_args!( - "Type '{}' does not represent any type", - reflect_value.reflect_type_path(), - )) - })?; - - let registration = type_registry.get(info.type_id()).ok_or_else(|| { - Error::custom(format_args!( - "Type `{}` is not registered in the type registry", - info.type_path(), - )) - })?; - - let reflect_serialize = registration.data::().ok_or_else(|| { - Error::custom(format_args!( - "Type `{}` did not register the `ReflectSerialize` type data. For certain types, this may need to be registered manually using `register_type_data`", - info.type_path(), - )) - })?; - - Ok(reflect_serialize.get_serializable(reflect_value)) -} - -/// A general purpose serializer for reflected types. -/// -/// This is the serializer counterpart to [`ReflectDeserializer`]. -/// -/// See [`TypedReflectSerializer`] for a serializer that serializes a known type. -/// -/// # Output -/// -/// This serializer will output a map with a single entry, -/// where the key is the _full_ [type path] of the reflected type -/// and the value is the serialized data. -/// -/// # Example -/// -/// ``` -/// # use bevy_reflect::prelude::*; -/// # use bevy_reflect::{TypeRegistry, serde::ReflectSerializer}; -/// #[derive(Reflect, PartialEq, Debug)] -/// #[type_path = "my_crate"] -/// struct MyStruct { -/// value: i32 -/// } -/// -/// let mut registry = TypeRegistry::default(); -/// registry.register::(); -/// -/// let input = MyStruct { value: 123 }; -/// -/// let reflect_serializer = ReflectSerializer::new(&input, ®istry); -/// let output = ron::to_string(&reflect_serializer).unwrap(); -/// -/// assert_eq!(output, r#"{"my_crate::MyStruct":(value:123)}"#); -/// ``` -/// -/// [`ReflectDeserializer`]: crate::serde::ReflectDeserializer -/// [type path]: crate::TypePath::type_path -pub struct ReflectSerializer<'a> { - pub value: &'a dyn PartialReflect, - pub registry: &'a TypeRegistry, -} - -impl<'a> ReflectSerializer<'a> { - pub fn new(value: &'a dyn PartialReflect, registry: &'a TypeRegistry) -> Self { - ReflectSerializer { value, registry } - } -} - -impl<'a> Serialize for ReflectSerializer<'a> { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - let mut state = serializer.serialize_map(Some(1))?; - state.serialize_entry( - self.value - .get_represented_type_info() - .ok_or_else(|| { - if self.value.is_dynamic() { - Error::custom(format_args!( - "cannot serialize dynamic value without represented type: {}", - self.value.reflect_type_path() - )) - } else { - Error::custom(format_args!( - "cannot get type info for {}", - self.value.reflect_type_path() - )) - } - })? - .type_path(), - &TypedReflectSerializer::new(self.value, self.registry), - )?; - state.end() - } -} - -/// A serializer for reflected types whose type will be known during deserialization. -/// -/// This is the serializer counterpart to [`TypedReflectDeserializer`]. -/// -/// See [`ReflectSerializer`] for a serializer that serializes an unknown type. -/// -/// # Output -/// -/// Since the type is expected to be known during deserialization, -/// this serializer will not output any additional type information, -/// such as the [type path]. -/// -/// Instead, it will output just the serialized data. -/// -/// # Example -/// -/// ``` -/// # use bevy_reflect::prelude::*; -/// # use bevy_reflect::{TypeRegistry, serde::TypedReflectSerializer}; -/// #[derive(Reflect, PartialEq, Debug)] -/// #[type_path = "my_crate"] -/// struct MyStruct { -/// value: i32 -/// } -/// -/// let mut registry = TypeRegistry::default(); -/// registry.register::(); -/// -/// let input = MyStruct { value: 123 }; -/// -/// let reflect_serializer = TypedReflectSerializer::new(&input, ®istry); -/// let output = ron::to_string(&reflect_serializer).unwrap(); -/// -/// assert_eq!(output, r#"(value:123)"#); -/// ``` -/// -/// [`TypedReflectDeserializer`]: crate::serde::TypedReflectDeserializer -/// [type path]: crate::TypePath::type_path -pub struct TypedReflectSerializer<'a> { - pub value: &'a dyn PartialReflect, - pub registry: &'a TypeRegistry, -} - -impl<'a> TypedReflectSerializer<'a> { - pub fn new(value: &'a dyn PartialReflect, registry: &'a TypeRegistry) -> Self { - TypedReflectSerializer { value, registry } - } -} - -impl<'a> Serialize for TypedReflectSerializer<'a> { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - // Handle both Value case and types that have a custom `Serialize` - let serializable = get_serializable::(self.value, self.registry); - if let Ok(serializable) = serializable { - return serializable.borrow().serialize(serializer); - } - - match self.value.reflect_ref() { - ReflectRef::Struct(value) => StructSerializer { - struct_value: value, - registry: self.registry, - } - .serialize(serializer), - ReflectRef::TupleStruct(value) => TupleStructSerializer { - tuple_struct: value, - registry: self.registry, - } - .serialize(serializer), - ReflectRef::Tuple(value) => TupleSerializer { - tuple: value, - registry: self.registry, - } - .serialize(serializer), - ReflectRef::List(value) => ListSerializer { - list: value, - registry: self.registry, - } - .serialize(serializer), - ReflectRef::Array(value) => ArraySerializer { - array: value, - registry: self.registry, - } - .serialize(serializer), - ReflectRef::Map(value) => MapSerializer { - map: value, - registry: self.registry, - } - .serialize(serializer), - ReflectRef::Set(value) => SetSerializer { - set: value, - registry: self.registry, - } - .serialize(serializer), - ReflectRef::Enum(value) => EnumSerializer { - enum_value: value, - registry: self.registry, - } - .serialize(serializer), - ReflectRef::Value(_) => Err(serializable.err().unwrap()), - } - } -} - -pub struct ReflectValueSerializer<'a> { - pub registry: &'a TypeRegistry, - pub value: &'a dyn PartialReflect, -} - -impl<'a> Serialize for ReflectValueSerializer<'a> { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - get_serializable::(self.value, self.registry)? - .borrow() - .serialize(serializer) - } -} - -pub struct StructSerializer<'a> { - pub struct_value: &'a dyn Struct, - pub registry: &'a TypeRegistry, -} - -impl<'a> Serialize for StructSerializer<'a> { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - let type_info = self - .struct_value - .get_represented_type_info() - .ok_or_else(|| { - Error::custom(format_args!( - "cannot get type info for {}", - self.struct_value.reflect_type_path() - )) - })?; - - let struct_info = match type_info { - TypeInfo::Struct(struct_info) => struct_info, - info => { - return Err(Error::custom(format_args!( - "expected struct type but received {info:?}" - ))); - } - }; - - let serialization_data = self - .registry - .get(type_info.type_id()) - .and_then(|registration| registration.data::()); - let ignored_len = serialization_data.map(SerializationData::len).unwrap_or(0); - let mut state = serializer.serialize_struct( - struct_info.type_path_table().ident().unwrap(), - self.struct_value.field_len() - ignored_len, - )?; - - for (index, value) in self.struct_value.iter_fields().enumerate() { - if serialization_data - .map(|data| data.is_field_skipped(index)) - .unwrap_or(false) - { - continue; - } - let key = struct_info.field_at(index).unwrap().name(); - state.serialize_field(key, &TypedReflectSerializer::new(value, self.registry))?; - } - state.end() - } -} - -pub struct TupleStructSerializer<'a> { - pub tuple_struct: &'a dyn TupleStruct, - pub registry: &'a TypeRegistry, -} - -impl<'a> Serialize for TupleStructSerializer<'a> { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - let type_info = self - .tuple_struct - .get_represented_type_info() - .ok_or_else(|| { - Error::custom(format_args!( - "cannot get type info for {}", - self.tuple_struct.reflect_type_path() - )) - })?; - - let tuple_struct_info = match type_info { - TypeInfo::TupleStruct(tuple_struct_info) => tuple_struct_info, - info => { - return Err(Error::custom(format_args!( - "expected tuple struct type but received {info:?}" - ))); - } - }; - - let serialization_data = self - .registry - .get(type_info.type_id()) - .and_then(|registration| registration.data::()); - let ignored_len = serialization_data.map(SerializationData::len).unwrap_or(0); - let mut state = serializer.serialize_tuple_struct( - tuple_struct_info.type_path_table().ident().unwrap(), - self.tuple_struct.field_len() - ignored_len, - )?; - - for (index, value) in self.tuple_struct.iter_fields().enumerate() { - if serialization_data - .map(|data| data.is_field_skipped(index)) - .unwrap_or(false) - { - continue; - } - state.serialize_field(&TypedReflectSerializer::new(value, self.registry))?; - } - state.end() - } -} - -pub struct EnumSerializer<'a> { - pub enum_value: &'a dyn Enum, - pub registry: &'a TypeRegistry, -} - -impl<'a> Serialize for EnumSerializer<'a> { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - let type_info = self.enum_value.get_represented_type_info().ok_or_else(|| { - Error::custom(format_args!( - "cannot get type info for {}", - self.enum_value.reflect_type_path() - )) - })?; - - let enum_info = match type_info { - TypeInfo::Enum(enum_info) => enum_info, - info => { - return Err(Error::custom(format_args!( - "expected enum type but received {info:?}" - ))); - } - }; - - let enum_name = enum_info.type_path_table().ident().unwrap(); - let variant_index = self.enum_value.variant_index() as u32; - let variant_info = enum_info - .variant_at(variant_index as usize) - .ok_or_else(|| { - Error::custom(format_args!( - "variant at index `{variant_index}` does not exist", - )) - })?; - let variant_name = variant_info.name(); - let variant_type = self.enum_value.variant_type(); - let field_len = self.enum_value.field_len(); - - match variant_type { - VariantType::Unit => { - if type_info.type_path_table().module_path() == Some("core::option") - && type_info.type_path_table().ident() == Some("Option") - { - serializer.serialize_none() - } else { - serializer.serialize_unit_variant(enum_name, variant_index, variant_name) - } - } - VariantType::Struct => { - let struct_info = match variant_info { - VariantInfo::Struct(struct_info) => struct_info, - info => { - return Err(Error::custom(format_args!( - "expected struct variant type but received {info:?}", - ))); - } - }; - - let mut state = serializer.serialize_struct_variant( - enum_name, - variant_index, - variant_name, - field_len, - )?; - for (index, field) in self.enum_value.iter_fields().enumerate() { - let field_info = struct_info.field_at(index).unwrap(); - state.serialize_field( - field_info.name(), - &TypedReflectSerializer::new(field.value(), self.registry), - )?; - } - state.end() - } - VariantType::Tuple if field_len == 1 => { - let field = self.enum_value.field_at(0).unwrap(); - - if type_info.type_path_table().module_path() == Some("core::option") - && type_info.type_path_table().ident() == Some("Option") - { - serializer.serialize_some(&TypedReflectSerializer::new(field, self.registry)) - } else { - serializer.serialize_newtype_variant( - enum_name, - variant_index, - variant_name, - &TypedReflectSerializer::new(field, self.registry), - ) - } - } - VariantType::Tuple => { - let mut state = serializer.serialize_tuple_variant( - enum_name, - variant_index, - variant_name, - field_len, - )?; - for field in self.enum_value.iter_fields() { - state.serialize_field(&TypedReflectSerializer::new( - field.value(), - self.registry, - ))?; - } - state.end() - } - } - } -} - -pub struct TupleSerializer<'a> { - pub tuple: &'a dyn Tuple, - pub registry: &'a TypeRegistry, -} - -impl<'a> Serialize for TupleSerializer<'a> { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - let mut state = serializer.serialize_tuple(self.tuple.field_len())?; - - for value in self.tuple.iter_fields() { - state.serialize_element(&TypedReflectSerializer::new(value, self.registry))?; - } - state.end() - } -} - -pub struct MapSerializer<'a> { - pub map: &'a dyn Map, - pub registry: &'a TypeRegistry, -} - -impl<'a> Serialize for MapSerializer<'a> { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - let mut state = serializer.serialize_map(Some(self.map.len()))?; - for (key, value) in self.map.iter() { - state.serialize_entry( - &TypedReflectSerializer::new(key, self.registry), - &TypedReflectSerializer::new(value, self.registry), - )?; - } - state.end() - } -} - -pub struct SetSerializer<'a> { - pub set: &'a dyn Set, - pub registry: &'a TypeRegistry, -} - -impl<'a> Serialize for SetSerializer<'a> { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - let mut state = serializer.serialize_seq(Some(self.set.len()))?; - for value in self.set.iter() { - state.serialize_element(&TypedReflectSerializer::new(value, self.registry))?; - } - state.end() - } -} - -pub struct ListSerializer<'a> { - pub list: &'a dyn List, - pub registry: &'a TypeRegistry, -} - -impl<'a> Serialize for ListSerializer<'a> { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - let mut state = serializer.serialize_seq(Some(self.list.len()))?; - for value in self.list.iter() { - state.serialize_element(&TypedReflectSerializer::new(value, self.registry))?; - } - state.end() - } -} - -pub struct ArraySerializer<'a> { - pub array: &'a dyn Array, - pub registry: &'a TypeRegistry, -} - -impl<'a> Serialize for ArraySerializer<'a> { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - let mut state = serializer.serialize_tuple(self.array.len())?; - for value in self.array.iter() { - state.serialize_element(&TypedReflectSerializer::new(value, self.registry))?; - } - state.end() - } -} - -#[cfg(test)] -mod tests { - use crate::serde::ReflectSerializer; - use crate::{self as bevy_reflect, PartialReflect, Struct}; - use crate::{Reflect, ReflectSerialize, TypeRegistry}; - use bevy_utils::{HashMap, HashSet}; - use ron::extensions::Extensions; - use ron::ser::PrettyConfig; - use serde::Serialize; - use std::f32::consts::PI; - use std::ops::RangeInclusive; - - #[derive(Reflect, Debug, PartialEq)] - struct MyStruct { - primitive_value: i8, - option_value: Option, - option_value_complex: Option, - tuple_value: (f32, usize), - list_value: Vec, - array_value: [i32; 5], - map_value: HashMap, - set_value: HashSet, - struct_value: SomeStruct, - tuple_struct_value: SomeTupleStruct, - unit_struct: SomeUnitStruct, - unit_enum: SomeEnum, - newtype_enum: SomeEnum, - tuple_enum: SomeEnum, - struct_enum: SomeEnum, - ignored_struct: SomeIgnoredStruct, - ignored_tuple_struct: SomeIgnoredTupleStruct, - ignored_struct_variant: SomeIgnoredEnum, - ignored_tuple_variant: SomeIgnoredEnum, - custom_serialize: CustomSerialize, - } - - #[derive(Reflect, Debug, PartialEq)] - struct SomeStruct { - foo: i64, - } - - #[derive(Reflect, Debug, PartialEq)] - struct SomeTupleStruct(String); - - #[derive(Reflect, Debug, PartialEq)] - struct SomeUnitStruct; - - #[derive(Reflect, Debug, PartialEq)] - struct SomeIgnoredStruct { - #[reflect(ignore)] - ignored: i32, - } - - #[derive(Reflect, Debug, PartialEq)] - struct SomeIgnoredTupleStruct(#[reflect(ignore)] i32); - - #[derive(Reflect, Debug, PartialEq)] - enum SomeEnum { - Unit, - NewType(usize), - Tuple(f32, f32), - Struct { foo: String }, - } - - #[derive(Reflect, Debug, PartialEq)] - enum SomeIgnoredEnum { - Tuple(#[reflect(ignore)] f32, #[reflect(ignore)] f32), - Struct { - #[reflect(ignore)] - foo: String, - }, - } - - #[derive(Reflect, Debug, PartialEq, Serialize)] - struct SomeSerializableStruct { - foo: i64, - } - - /// Implements a custom serialize using `#[reflect(Serialize)]`. - /// - /// For testing purposes, this just uses the generated one from deriving Serialize. - #[derive(Reflect, Debug, PartialEq, Serialize)] - #[reflect(Serialize)] - struct CustomSerialize { - value: usize, - #[serde(rename = "renamed")] - inner_struct: SomeSerializableStruct, - } - - fn get_registry() -> TypeRegistry { - let mut registry = TypeRegistry::default(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register::(); - registry.register_type_data::(); - registry.register::(); - registry.register::>(); - registry.register_type_data::, ReflectSerialize>(); - registry - } - - fn get_my_struct() -> MyStruct { - let mut map = HashMap::new(); - map.insert(64, 32); - - let mut set = HashSet::new(); - set.insert(64); - - MyStruct { - primitive_value: 123, - option_value: Some(String::from("Hello world!")), - option_value_complex: Some(SomeStruct { foo: 123 }), - tuple_value: (PI, 1337), - list_value: vec![-2, -1, 0, 1, 2], - array_value: [-2, -1, 0, 1, 2], - map_value: map, - set_value: set, - struct_value: SomeStruct { foo: 999999999 }, - tuple_struct_value: SomeTupleStruct(String::from("Tuple Struct")), - unit_struct: SomeUnitStruct, - unit_enum: SomeEnum::Unit, - newtype_enum: SomeEnum::NewType(123), - tuple_enum: SomeEnum::Tuple(1.23, 3.21), - struct_enum: SomeEnum::Struct { - foo: String::from("Struct variant value"), - }, - ignored_struct: SomeIgnoredStruct { ignored: 123 }, - ignored_tuple_struct: SomeIgnoredTupleStruct(123), - ignored_struct_variant: SomeIgnoredEnum::Struct { - foo: String::from("Struct Variant"), - }, - ignored_tuple_variant: SomeIgnoredEnum::Tuple(1.23, 3.45), - custom_serialize: CustomSerialize { - value: 100, - inner_struct: SomeSerializableStruct { foo: 101 }, - }, - } - } - - #[test] - fn should_serialize() { - let input = get_my_struct(); - let registry = get_registry(); - - let serializer = ReflectSerializer::new(&input, ®istry); - - let config = PrettyConfig::default() - .new_line(String::from("\n")) - .indentor(String::from(" ")); - - let output = ron::ser::to_string_pretty(&serializer, config).unwrap(); - let expected = r#"{ - "bevy_reflect::serde::ser::tests::MyStruct": ( - primitive_value: 123, - option_value: Some("Hello world!"), - option_value_complex: Some(( - foo: 123, - )), - tuple_value: (3.1415927, 1337), - list_value: [ - -2, - -1, - 0, - 1, - 2, - ], - array_value: (-2, -1, 0, 1, 2), - map_value: { - 64: 32, - }, - set_value: [ - 64, - ], - struct_value: ( - foo: 999999999, - ), - tuple_struct_value: ("Tuple Struct"), - unit_struct: (), - unit_enum: Unit, - newtype_enum: NewType(123), - tuple_enum: Tuple(1.23, 3.21), - struct_enum: Struct( - foo: "Struct variant value", - ), - ignored_struct: (), - ignored_tuple_struct: (), - ignored_struct_variant: Struct(), - ignored_tuple_variant: Tuple(), - custom_serialize: ( - value: 100, - renamed: ( - foo: 101, - ), - ), - ), -}"#; - assert_eq!(expected, output); - } - - #[test] - fn should_serialize_option() { - #[derive(Reflect, Debug, PartialEq)] - struct OptionTest { - none: Option<()>, - simple: Option, - complex: Option, - } - - let value = OptionTest { - none: None, - simple: Some(String::from("Hello world!")), - complex: Some(SomeStruct { foo: 123 }), - }; - - let registry = get_registry(); - let serializer = ReflectSerializer::new(&value, ®istry); - - // === Normal === // - let config = PrettyConfig::default() - .new_line(String::from("\n")) - .indentor(String::from(" ")); - - let output = ron::ser::to_string_pretty(&serializer, config).unwrap(); - let expected = r#"{ - "bevy_reflect::serde::ser::tests::OptionTest": ( - none: None, - simple: Some("Hello world!"), - complex: Some(( - foo: 123, - )), - ), -}"#; - - assert_eq!(expected, output); - - // === Implicit Some === // - let config = PrettyConfig::default() - .new_line(String::from("\n")) - .extensions(Extensions::IMPLICIT_SOME) - .indentor(String::from(" ")); - - let output = ron::ser::to_string_pretty(&serializer, config).unwrap(); - let expected = r#"#![enable(implicit_some)] -{ - "bevy_reflect::serde::ser::tests::OptionTest": ( - none: None, - simple: "Hello world!", - complex: ( - foo: 123, - ), - ), -}"#; - - assert_eq!(expected, output); - } - - #[test] - fn enum_should_serialize() { - #[derive(Reflect)] - enum MyEnum { - Unit, - NewType(usize), - Tuple(f32, f32), - Struct { value: String }, - } - - let mut registry = get_registry(); - registry.register::(); - - let config = PrettyConfig::default().new_line(String::from("\n")); - - // === Unit Variant === // - let value = MyEnum::Unit; - let serializer = ReflectSerializer::new(&value, ®istry); - let output = ron::ser::to_string_pretty(&serializer, config.clone()).unwrap(); - let expected = r#"{ - "bevy_reflect::serde::ser::tests::MyEnum": Unit, -}"#; - assert_eq!(expected, output); - - // === NewType Variant === // - let value = MyEnum::NewType(123); - let serializer = ReflectSerializer::new(&value, ®istry); - let output = ron::ser::to_string_pretty(&serializer, config.clone()).unwrap(); - let expected = r#"{ - "bevy_reflect::serde::ser::tests::MyEnum": NewType(123), -}"#; - assert_eq!(expected, output); - - // === Tuple Variant === // - let value = MyEnum::Tuple(1.23, 3.21); - let serializer = ReflectSerializer::new(&value, ®istry); - let output = ron::ser::to_string_pretty(&serializer, config.clone()).unwrap(); - let expected = r#"{ - "bevy_reflect::serde::ser::tests::MyEnum": Tuple(1.23, 3.21), -}"#; - assert_eq!(expected, output); - - // === Struct Variant === // - let value = MyEnum::Struct { - value: String::from("I <3 Enums"), - }; - let serializer = ReflectSerializer::new(&value, ®istry); - let output = ron::ser::to_string_pretty(&serializer, config).unwrap(); - let expected = r#"{ - "bevy_reflect::serde::ser::tests::MyEnum": Struct( - value: "I <3 Enums", - ), -}"#; - assert_eq!(expected, output); - } - - #[test] - fn should_serialize_non_self_describing_binary() { - let input = get_my_struct(); - let registry = get_registry(); - - let serializer = ReflectSerializer::new(&input, ®istry); - let bytes = bincode::serialize(&serializer).unwrap(); - - let expected: Vec = vec![ - 1, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 98, 101, 118, 121, 95, 114, 101, 102, - 108, 101, 99, 116, 58, 58, 115, 101, 114, 100, 101, 58, 58, 115, 101, 114, 58, 58, 116, - 101, 115, 116, 115, 58, 58, 77, 121, 83, 116, 114, 117, 99, 116, 123, 1, 12, 0, 0, 0, - 0, 0, 0, 0, 72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33, 1, 123, 0, 0, 0, - 0, 0, 0, 0, 219, 15, 73, 64, 57, 5, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 254, 255, - 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 254, 255, 255, 255, - 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 32, - 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 255, 201, 154, 59, 0, 0, 0, 0, 12, 0, - 0, 0, 0, 0, 0, 0, 84, 117, 112, 108, 101, 32, 83, 116, 114, 117, 99, 116, 0, 0, 0, 0, - 1, 0, 0, 0, 123, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 164, 112, 157, 63, 164, 112, 77, 64, - 3, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 83, 116, 114, 117, 99, 116, 32, 118, 97, 114, 105, - 97, 110, 116, 32, 118, 97, 108, 117, 101, 1, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, - 0, 0, 101, 0, 0, 0, 0, 0, 0, 0, - ]; - - assert_eq!(expected, bytes); - } - - #[test] - fn should_serialize_self_describing_binary() { - let input = get_my_struct(); - let registry = get_registry(); - - let serializer = ReflectSerializer::new(&input, ®istry); - let bytes: Vec = rmp_serde::to_vec(&serializer).unwrap(); - - let expected: Vec = vec![ - 129, 217, 41, 98, 101, 118, 121, 95, 114, 101, 102, 108, 101, 99, 116, 58, 58, 115, - 101, 114, 100, 101, 58, 58, 115, 101, 114, 58, 58, 116, 101, 115, 116, 115, 58, 58, 77, - 121, 83, 116, 114, 117, 99, 116, 220, 0, 20, 123, 172, 72, 101, 108, 108, 111, 32, 119, - 111, 114, 108, 100, 33, 145, 123, 146, 202, 64, 73, 15, 219, 205, 5, 57, 149, 254, 255, - 0, 1, 2, 149, 254, 255, 0, 1, 2, 129, 64, 32, 145, 64, 145, 206, 59, 154, 201, 255, - 145, 172, 84, 117, 112, 108, 101, 32, 83, 116, 114, 117, 99, 116, 144, 164, 85, 110, - 105, 116, 129, 167, 78, 101, 119, 84, 121, 112, 101, 123, 129, 165, 84, 117, 112, 108, - 101, 146, 202, 63, 157, 112, 164, 202, 64, 77, 112, 164, 129, 166, 83, 116, 114, 117, - 99, 116, 145, 180, 83, 116, 114, 117, 99, 116, 32, 118, 97, 114, 105, 97, 110, 116, 32, - 118, 97, 108, 117, 101, 144, 144, 129, 166, 83, 116, 114, 117, 99, 116, 144, 129, 165, - 84, 117, 112, 108, 101, 144, 146, 100, 145, 101, - ]; - - assert_eq!(expected, bytes); - } - - #[test] - fn should_serialize_dynamic_option() { - #[derive(Default, Reflect)] - struct OtherStruct { - some: Option, - none: Option, - } - - let value = OtherStruct { - some: Some(SomeStruct { foo: 999999999 }), - none: None, - }; - let dynamic = value.clone_dynamic(); - let reflect = dynamic.as_partial_reflect(); - - let registry = get_registry(); - - let serializer = ReflectSerializer::new(reflect, ®istry); - - let mut buf = Vec::new(); - - let format = serde_json::ser::PrettyFormatter::with_indent(b" "); - let mut ser = serde_json::Serializer::with_formatter(&mut buf, format); - - serializer.serialize(&mut ser).unwrap(); - - let output = std::str::from_utf8(&buf).unwrap(); - let expected = r#"{ - "bevy_reflect::serde::ser::tests::OtherStruct": { - "some": { - "foo": 999999999 - }, - "none": null - } -}"#; - - assert_eq!(expected, output); - } - - #[test] - fn should_return_error_if_missing_registration() { - let value = RangeInclusive::::new(0.0, 1.0); - let registry = TypeRegistry::new(); - - let serializer = ReflectSerializer::new(&value, ®istry); - let error = ron::ser::to_string(&serializer).unwrap_err(); - assert_eq!( - error, - ron::Error::Message( - "Type `core::ops::RangeInclusive` is not registered in the type registry" - .to_string() - ) - ); - } - - #[test] - fn should_return_error_if_missing_type_data() { - let value = RangeInclusive::::new(0.0, 1.0); - let mut registry = TypeRegistry::new(); - registry.register::>(); - - let serializer = ReflectSerializer::new(&value, ®istry); - let error = ron::ser::to_string(&serializer).unwrap_err(); - assert_eq!( - error, - ron::Error::Message( - "Type `core::ops::RangeInclusive` did not register the `ReflectSerialize` type data. For certain types, this may need to be registered manually using `register_type_data`".to_string() - ) - ); - } -} diff --git a/crates/bevy_reflect/src/serde/ser/arrays.rs b/crates/bevy_reflect/src/serde/ser/arrays.rs new file mode 100644 index 0000000000..eb84919dfd --- /dev/null +++ b/crates/bevy_reflect/src/serde/ser/arrays.rs @@ -0,0 +1,29 @@ +use crate::serde::TypedReflectSerializer; +use crate::{Array, TypeRegistry}; +use serde::ser::SerializeTuple; +use serde::Serialize; + +/// A serializer for [`Array`] values. +pub(super) struct ArraySerializer<'a> { + array: &'a dyn Array, + registry: &'a TypeRegistry, +} + +impl<'a> ArraySerializer<'a> { + pub fn new(array: &'a dyn Array, registry: &'a TypeRegistry) -> Self { + Self { array, registry } + } +} + +impl<'a> Serialize for ArraySerializer<'a> { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_tuple(self.array.len())?; + for value in self.array.iter() { + state.serialize_element(&TypedReflectSerializer::new(value, self.registry))?; + } + state.end() + } +} diff --git a/crates/bevy_reflect/src/serde/ser/enums.rs b/crates/bevy_reflect/src/serde/ser/enums.rs new file mode 100644 index 0000000000..da151cc894 --- /dev/null +++ b/crates/bevy_reflect/src/serde/ser/enums.rs @@ -0,0 +1,123 @@ +use crate::serde::TypedReflectSerializer; +use crate::{Enum, TypeInfo, TypeRegistry, VariantInfo, VariantType}; +use serde::ser::{Error, SerializeStructVariant, SerializeTupleVariant}; +use serde::Serialize; + +/// A serializer for [`Enum`] values. +pub(super) struct EnumSerializer<'a> { + enum_value: &'a dyn Enum, + registry: &'a TypeRegistry, +} + +impl<'a> EnumSerializer<'a> { + pub fn new(enum_value: &'a dyn Enum, registry: &'a TypeRegistry) -> Self { + Self { + enum_value, + registry, + } + } +} + +impl<'a> Serialize for EnumSerializer<'a> { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let type_info = self.enum_value.get_represented_type_info().ok_or_else(|| { + Error::custom(format_args!( + "cannot get type info for {}", + self.enum_value.reflect_type_path() + )) + })?; + + let enum_info = match type_info { + TypeInfo::Enum(enum_info) => enum_info, + info => { + return Err(Error::custom(format_args!( + "expected enum type but received {info:?}" + ))); + } + }; + + let enum_name = enum_info.type_path_table().ident().unwrap(); + let variant_index = self.enum_value.variant_index() as u32; + let variant_info = enum_info + .variant_at(variant_index as usize) + .ok_or_else(|| { + Error::custom(format_args!( + "variant at index `{variant_index}` does not exist", + )) + })?; + let variant_name = variant_info.name(); + let variant_type = self.enum_value.variant_type(); + let field_len = self.enum_value.field_len(); + + match variant_type { + VariantType::Unit => { + if type_info.type_path_table().module_path() == Some("core::option") + && type_info.type_path_table().ident() == Some("Option") + { + serializer.serialize_none() + } else { + serializer.serialize_unit_variant(enum_name, variant_index, variant_name) + } + } + VariantType::Struct => { + let struct_info = match variant_info { + VariantInfo::Struct(struct_info) => struct_info, + info => { + return Err(Error::custom(format_args!( + "expected struct variant type but received {info:?}", + ))); + } + }; + + let mut state = serializer.serialize_struct_variant( + enum_name, + variant_index, + variant_name, + field_len, + )?; + for (index, field) in self.enum_value.iter_fields().enumerate() { + let field_info = struct_info.field_at(index).unwrap(); + state.serialize_field( + field_info.name(), + &TypedReflectSerializer::new(field.value(), self.registry), + )?; + } + state.end() + } + VariantType::Tuple if field_len == 1 => { + let field = self.enum_value.field_at(0).unwrap(); + + if type_info.type_path_table().module_path() == Some("core::option") + && type_info.type_path_table().ident() == Some("Option") + { + serializer.serialize_some(&TypedReflectSerializer::new(field, self.registry)) + } else { + serializer.serialize_newtype_variant( + enum_name, + variant_index, + variant_name, + &TypedReflectSerializer::new(field, self.registry), + ) + } + } + VariantType::Tuple => { + let mut state = serializer.serialize_tuple_variant( + enum_name, + variant_index, + variant_name, + field_len, + )?; + for field in self.enum_value.iter_fields() { + state.serialize_field(&TypedReflectSerializer::new( + field.value(), + self.registry, + ))?; + } + state.end() + } + } + } +} diff --git a/crates/bevy_reflect/src/serde/ser/lists.rs b/crates/bevy_reflect/src/serde/ser/lists.rs new file mode 100644 index 0000000000..6e6b98958b --- /dev/null +++ b/crates/bevy_reflect/src/serde/ser/lists.rs @@ -0,0 +1,29 @@ +use crate::serde::TypedReflectSerializer; +use crate::{List, TypeRegistry}; +use serde::ser::SerializeSeq; +use serde::Serialize; + +/// A serializer for [`List`] values. +pub(super) struct ListSerializer<'a> { + list: &'a dyn List, + registry: &'a TypeRegistry, +} + +impl<'a> ListSerializer<'a> { + pub fn new(list: &'a dyn List, registry: &'a TypeRegistry) -> Self { + Self { list, registry } + } +} + +impl<'a> Serialize for ListSerializer<'a> { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_seq(Some(self.list.len()))?; + for value in self.list.iter() { + state.serialize_element(&TypedReflectSerializer::new(value, self.registry))?; + } + state.end() + } +} diff --git a/crates/bevy_reflect/src/serde/ser/maps.rs b/crates/bevy_reflect/src/serde/ser/maps.rs new file mode 100644 index 0000000000..589cfae3d1 --- /dev/null +++ b/crates/bevy_reflect/src/serde/ser/maps.rs @@ -0,0 +1,32 @@ +use crate::serde::TypedReflectSerializer; +use crate::{Map, TypeRegistry}; +use serde::ser::SerializeMap; +use serde::Serialize; + +/// A serializer for [`Map`] values. +pub(super) struct MapSerializer<'a> { + map: &'a dyn Map, + registry: &'a TypeRegistry, +} + +impl<'a> MapSerializer<'a> { + pub fn new(map: &'a dyn Map, registry: &'a TypeRegistry) -> Self { + Self { map, registry } + } +} + +impl<'a> Serialize for MapSerializer<'a> { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_map(Some(self.map.len()))?; + for (key, value) in self.map.iter() { + state.serialize_entry( + &TypedReflectSerializer::new(key, self.registry), + &TypedReflectSerializer::new(value, self.registry), + )?; + } + state.end() + } +} diff --git a/crates/bevy_reflect/src/serde/ser/mod.rs b/crates/bevy_reflect/src/serde/ser/mod.rs new file mode 100644 index 0000000000..85876fabf2 --- /dev/null +++ b/crates/bevy_reflect/src/serde/ser/mod.rs @@ -0,0 +1,456 @@ +pub use serializable::*; +pub use serializer::*; + +mod arrays; +mod enums; +mod lists; +mod maps; +mod serializable; +mod serializer; +mod sets; +mod structs; +mod tuple_structs; +mod tuples; + +#[cfg(test)] +mod tests { + use crate::serde::ReflectSerializer; + use crate::{self as bevy_reflect, PartialReflect, Struct}; + use crate::{Reflect, ReflectSerialize, TypeRegistry}; + use bevy_utils::{HashMap, HashSet}; + use ron::extensions::Extensions; + use ron::ser::PrettyConfig; + use serde::Serialize; + use std::f32::consts::PI; + use std::ops::RangeInclusive; + + #[derive(Reflect, Debug, PartialEq)] + struct MyStruct { + primitive_value: i8, + option_value: Option, + option_value_complex: Option, + tuple_value: (f32, usize), + list_value: Vec, + array_value: [i32; 5], + map_value: HashMap, + set_value: HashSet, + struct_value: SomeStruct, + tuple_struct_value: SomeTupleStruct, + unit_struct: SomeUnitStruct, + unit_enum: SomeEnum, + newtype_enum: SomeEnum, + tuple_enum: SomeEnum, + struct_enum: SomeEnum, + ignored_struct: SomeIgnoredStruct, + ignored_tuple_struct: SomeIgnoredTupleStruct, + ignored_struct_variant: SomeIgnoredEnum, + ignored_tuple_variant: SomeIgnoredEnum, + custom_serialize: CustomSerialize, + } + + #[derive(Reflect, Debug, PartialEq)] + struct SomeStruct { + foo: i64, + } + + #[derive(Reflect, Debug, PartialEq)] + struct SomeTupleStruct(String); + + #[derive(Reflect, Debug, PartialEq)] + struct SomeUnitStruct; + + #[derive(Reflect, Debug, PartialEq)] + struct SomeIgnoredStruct { + #[reflect(ignore)] + ignored: i32, + } + + #[derive(Reflect, Debug, PartialEq)] + struct SomeIgnoredTupleStruct(#[reflect(ignore)] i32); + + #[derive(Reflect, Debug, PartialEq)] + enum SomeEnum { + Unit, + NewType(usize), + Tuple(f32, f32), + Struct { foo: String }, + } + + #[derive(Reflect, Debug, PartialEq)] + enum SomeIgnoredEnum { + Tuple(#[reflect(ignore)] f32, #[reflect(ignore)] f32), + Struct { + #[reflect(ignore)] + foo: String, + }, + } + + #[derive(Reflect, Debug, PartialEq, Serialize)] + struct SomeSerializableStruct { + foo: i64, + } + + /// Implements a custom serialize using `#[reflect(Serialize)]`. + /// + /// For testing purposes, this just uses the generated one from deriving Serialize. + #[derive(Reflect, Debug, PartialEq, Serialize)] + #[reflect(Serialize)] + struct CustomSerialize { + value: usize, + #[serde(rename = "renamed")] + inner_struct: SomeSerializableStruct, + } + + fn get_registry() -> TypeRegistry { + let mut registry = TypeRegistry::default(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register_type_data::(); + registry.register::(); + registry.register::>(); + registry.register_type_data::, ReflectSerialize>(); + registry + } + + fn get_my_struct() -> MyStruct { + let mut map = HashMap::new(); + map.insert(64, 32); + + let mut set = HashSet::new(); + set.insert(64); + + MyStruct { + primitive_value: 123, + option_value: Some(String::from("Hello world!")), + option_value_complex: Some(SomeStruct { foo: 123 }), + tuple_value: (PI, 1337), + list_value: vec![-2, -1, 0, 1, 2], + array_value: [-2, -1, 0, 1, 2], + map_value: map, + set_value: set, + struct_value: SomeStruct { foo: 999999999 }, + tuple_struct_value: SomeTupleStruct(String::from("Tuple Struct")), + unit_struct: SomeUnitStruct, + unit_enum: SomeEnum::Unit, + newtype_enum: SomeEnum::NewType(123), + tuple_enum: SomeEnum::Tuple(1.23, 3.21), + struct_enum: SomeEnum::Struct { + foo: String::from("Struct variant value"), + }, + ignored_struct: SomeIgnoredStruct { ignored: 123 }, + ignored_tuple_struct: SomeIgnoredTupleStruct(123), + ignored_struct_variant: SomeIgnoredEnum::Struct { + foo: String::from("Struct Variant"), + }, + ignored_tuple_variant: SomeIgnoredEnum::Tuple(1.23, 3.45), + custom_serialize: CustomSerialize { + value: 100, + inner_struct: SomeSerializableStruct { foo: 101 }, + }, + } + } + + #[test] + fn should_serialize() { + let input = get_my_struct(); + let registry = get_registry(); + + let serializer = ReflectSerializer::new(&input, ®istry); + + let config = PrettyConfig::default() + .new_line(String::from("\n")) + .indentor(String::from(" ")); + + let output = ron::ser::to_string_pretty(&serializer, config).unwrap(); + let expected = r#"{ + "bevy_reflect::serde::ser::tests::MyStruct": ( + primitive_value: 123, + option_value: Some("Hello world!"), + option_value_complex: Some(( + foo: 123, + )), + tuple_value: (3.1415927, 1337), + list_value: [ + -2, + -1, + 0, + 1, + 2, + ], + array_value: (-2, -1, 0, 1, 2), + map_value: { + 64: 32, + }, + set_value: [ + 64, + ], + struct_value: ( + foo: 999999999, + ), + tuple_struct_value: ("Tuple Struct"), + unit_struct: (), + unit_enum: Unit, + newtype_enum: NewType(123), + tuple_enum: Tuple(1.23, 3.21), + struct_enum: Struct( + foo: "Struct variant value", + ), + ignored_struct: (), + ignored_tuple_struct: (), + ignored_struct_variant: Struct(), + ignored_tuple_variant: Tuple(), + custom_serialize: ( + value: 100, + renamed: ( + foo: 101, + ), + ), + ), +}"#; + assert_eq!(expected, output); + } + + #[test] + fn should_serialize_option() { + #[derive(Reflect, Debug, PartialEq)] + struct OptionTest { + none: Option<()>, + simple: Option, + complex: Option, + } + + let value = OptionTest { + none: None, + simple: Some(String::from("Hello world!")), + complex: Some(SomeStruct { foo: 123 }), + }; + + let registry = get_registry(); + let serializer = ReflectSerializer::new(&value, ®istry); + + // === Normal === // + let config = PrettyConfig::default() + .new_line(String::from("\n")) + .indentor(String::from(" ")); + + let output = ron::ser::to_string_pretty(&serializer, config).unwrap(); + let expected = r#"{ + "bevy_reflect::serde::ser::tests::OptionTest": ( + none: None, + simple: Some("Hello world!"), + complex: Some(( + foo: 123, + )), + ), +}"#; + + assert_eq!(expected, output); + + // === Implicit Some === // + let config = PrettyConfig::default() + .new_line(String::from("\n")) + .extensions(Extensions::IMPLICIT_SOME) + .indentor(String::from(" ")); + + let output = ron::ser::to_string_pretty(&serializer, config).unwrap(); + let expected = r#"#![enable(implicit_some)] +{ + "bevy_reflect::serde::ser::tests::OptionTest": ( + none: None, + simple: "Hello world!", + complex: ( + foo: 123, + ), + ), +}"#; + + assert_eq!(expected, output); + } + + #[test] + fn enum_should_serialize() { + #[derive(Reflect)] + enum MyEnum { + Unit, + NewType(usize), + Tuple(f32, f32), + Struct { value: String }, + } + + let mut registry = get_registry(); + registry.register::(); + + let config = PrettyConfig::default().new_line(String::from("\n")); + + // === Unit Variant === // + let value = MyEnum::Unit; + let serializer = ReflectSerializer::new(&value, ®istry); + let output = ron::ser::to_string_pretty(&serializer, config.clone()).unwrap(); + let expected = r#"{ + "bevy_reflect::serde::ser::tests::MyEnum": Unit, +}"#; + assert_eq!(expected, output); + + // === NewType Variant === // + let value = MyEnum::NewType(123); + let serializer = ReflectSerializer::new(&value, ®istry); + let output = ron::ser::to_string_pretty(&serializer, config.clone()).unwrap(); + let expected = r#"{ + "bevy_reflect::serde::ser::tests::MyEnum": NewType(123), +}"#; + assert_eq!(expected, output); + + // === Tuple Variant === // + let value = MyEnum::Tuple(1.23, 3.21); + let serializer = ReflectSerializer::new(&value, ®istry); + let output = ron::ser::to_string_pretty(&serializer, config.clone()).unwrap(); + let expected = r#"{ + "bevy_reflect::serde::ser::tests::MyEnum": Tuple(1.23, 3.21), +}"#; + assert_eq!(expected, output); + + // === Struct Variant === // + let value = MyEnum::Struct { + value: String::from("I <3 Enums"), + }; + let serializer = ReflectSerializer::new(&value, ®istry); + let output = ron::ser::to_string_pretty(&serializer, config).unwrap(); + let expected = r#"{ + "bevy_reflect::serde::ser::tests::MyEnum": Struct( + value: "I <3 Enums", + ), +}"#; + assert_eq!(expected, output); + } + + #[test] + fn should_serialize_non_self_describing_binary() { + let input = get_my_struct(); + let registry = get_registry(); + + let serializer = ReflectSerializer::new(&input, ®istry); + let bytes = bincode::serialize(&serializer).unwrap(); + + let expected: Vec = vec![ + 1, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 98, 101, 118, 121, 95, 114, 101, 102, + 108, 101, 99, 116, 58, 58, 115, 101, 114, 100, 101, 58, 58, 115, 101, 114, 58, 58, 116, + 101, 115, 116, 115, 58, 58, 77, 121, 83, 116, 114, 117, 99, 116, 123, 1, 12, 0, 0, 0, + 0, 0, 0, 0, 72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33, 1, 123, 0, 0, 0, + 0, 0, 0, 0, 219, 15, 73, 64, 57, 5, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 254, 255, + 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 254, 255, 255, 255, + 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 32, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 255, 201, 154, 59, 0, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 84, 117, 112, 108, 101, 32, 83, 116, 114, 117, 99, 116, 0, 0, 0, 0, + 1, 0, 0, 0, 123, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 164, 112, 157, 63, 164, 112, 77, 64, + 3, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 83, 116, 114, 117, 99, 116, 32, 118, 97, 114, 105, + 97, 110, 116, 32, 118, 97, 108, 117, 101, 1, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, + 0, 0, 101, 0, 0, 0, 0, 0, 0, 0, + ]; + + assert_eq!(expected, bytes); + } + + #[test] + fn should_serialize_self_describing_binary() { + let input = get_my_struct(); + let registry = get_registry(); + + let serializer = ReflectSerializer::new(&input, ®istry); + let bytes: Vec = rmp_serde::to_vec(&serializer).unwrap(); + + let expected: Vec = vec![ + 129, 217, 41, 98, 101, 118, 121, 95, 114, 101, 102, 108, 101, 99, 116, 58, 58, 115, + 101, 114, 100, 101, 58, 58, 115, 101, 114, 58, 58, 116, 101, 115, 116, 115, 58, 58, 77, + 121, 83, 116, 114, 117, 99, 116, 220, 0, 20, 123, 172, 72, 101, 108, 108, 111, 32, 119, + 111, 114, 108, 100, 33, 145, 123, 146, 202, 64, 73, 15, 219, 205, 5, 57, 149, 254, 255, + 0, 1, 2, 149, 254, 255, 0, 1, 2, 129, 64, 32, 145, 64, 145, 206, 59, 154, 201, 255, + 145, 172, 84, 117, 112, 108, 101, 32, 83, 116, 114, 117, 99, 116, 144, 164, 85, 110, + 105, 116, 129, 167, 78, 101, 119, 84, 121, 112, 101, 123, 129, 165, 84, 117, 112, 108, + 101, 146, 202, 63, 157, 112, 164, 202, 64, 77, 112, 164, 129, 166, 83, 116, 114, 117, + 99, 116, 145, 180, 83, 116, 114, 117, 99, 116, 32, 118, 97, 114, 105, 97, 110, 116, 32, + 118, 97, 108, 117, 101, 144, 144, 129, 166, 83, 116, 114, 117, 99, 116, 144, 129, 165, + 84, 117, 112, 108, 101, 144, 146, 100, 145, 101, + ]; + + assert_eq!(expected, bytes); + } + + #[test] + fn should_serialize_dynamic_option() { + #[derive(Default, Reflect)] + struct OtherStruct { + some: Option, + none: Option, + } + + let value = OtherStruct { + some: Some(SomeStruct { foo: 999999999 }), + none: None, + }; + let dynamic = value.clone_dynamic(); + let reflect = dynamic.as_partial_reflect(); + + let registry = get_registry(); + + let serializer = ReflectSerializer::new(reflect, ®istry); + + let mut buf = Vec::new(); + + let format = serde_json::ser::PrettyFormatter::with_indent(b" "); + let mut ser = serde_json::Serializer::with_formatter(&mut buf, format); + + serializer.serialize(&mut ser).unwrap(); + + let output = std::str::from_utf8(&buf).unwrap(); + let expected = r#"{ + "bevy_reflect::serde::ser::tests::OtherStruct": { + "some": { + "foo": 999999999 + }, + "none": null + } +}"#; + + assert_eq!(expected, output); + } + + #[test] + fn should_return_error_if_missing_registration() { + let value = RangeInclusive::::new(0.0, 1.0); + let registry = TypeRegistry::new(); + + let serializer = ReflectSerializer::new(&value, ®istry); + let error = ron::ser::to_string(&serializer).unwrap_err(); + assert_eq!( + error, + ron::Error::Message( + "Type `core::ops::RangeInclusive` is not registered in the type registry" + .to_string() + ) + ); + } + + #[test] + fn should_return_error_if_missing_type_data() { + let value = RangeInclusive::::new(0.0, 1.0); + let mut registry = TypeRegistry::new(); + registry.register::>(); + + let serializer = ReflectSerializer::new(&value, ®istry); + let error = ron::ser::to_string(&serializer).unwrap_err(); + assert_eq!( + error, + ron::Error::Message( + "Type `core::ops::RangeInclusive` did not register the `ReflectSerialize` type data. For certain types, this may need to be registered manually using `register_type_data`".to_string() + ) + ); + } +} diff --git a/crates/bevy_reflect/src/serde/ser/serializable.rs b/crates/bevy_reflect/src/serde/ser/serializable.rs new file mode 100644 index 0000000000..9c285816f2 --- /dev/null +++ b/crates/bevy_reflect/src/serde/ser/serializable.rs @@ -0,0 +1,66 @@ +use crate::{PartialReflect, ReflectSerialize, TypeRegistry}; +use serde::ser::Error; +use std::ops::Deref; + +/// A type-erased serializable value. +pub enum Serializable<'a> { + Owned(Box), + Borrowed(&'a dyn erased_serde::Serialize), +} + +impl<'a> Serializable<'a> { + /// Attempts to create a [`Serializable`] from a [`PartialReflect`] value. + /// + /// Returns an error if any of the following conditions are met: + /// - The underlying type of `value` does not implement [`Reflect`]. + /// - The underlying type of `value` does not represent any type (via [`PartialReflect::get_represented_type_info`]). + /// - The represented type of `value` is not registered in the `type_registry`. + /// - The represented type of `value` did not register the [`ReflectSerialize`] type data. + /// + /// [`Reflect`]: crate::Reflect + pub fn try_from_reflect_value( + value: &'a dyn PartialReflect, + type_registry: &TypeRegistry, + ) -> Result, E> { + let value = value.try_as_reflect().ok_or_else(|| { + Error::custom(format_args!( + "Type '{}' does not implement `Reflect`", + value.reflect_type_path() + )) + })?; + + let info = value.get_represented_type_info().ok_or_else(|| { + Error::custom(format_args!( + "Type '{}' does not represent any type", + value.reflect_type_path(), + )) + })?; + + let registration = type_registry.get(info.type_id()).ok_or_else(|| { + Error::custom(format_args!( + "Type `{}` is not registered in the type registry", + info.type_path(), + )) + })?; + + let reflect_serialize = registration.data::().ok_or_else(|| { + Error::custom(format_args!( + "Type `{}` did not register the `ReflectSerialize` type data. For certain types, this may need to be registered manually using `register_type_data`", + info.type_path(), + )) + })?; + + Ok(reflect_serialize.get_serializable(value)) + } +} + +impl<'a> Deref for Serializable<'a> { + type Target = dyn erased_serde::Serialize + 'a; + + fn deref(&self) -> &Self::Target { + match self { + Serializable::Borrowed(serialize) => serialize, + Serializable::Owned(serialize) => serialize, + } + } +} diff --git a/crates/bevy_reflect/src/serde/ser/serializer.rs b/crates/bevy_reflect/src/serde/ser/serializer.rs new file mode 100644 index 0000000000..eb3afe96f8 --- /dev/null +++ b/crates/bevy_reflect/src/serde/ser/serializer.rs @@ -0,0 +1,179 @@ +use crate::serde::ser::arrays::ArraySerializer; +use crate::serde::ser::enums::EnumSerializer; +use crate::serde::ser::lists::ListSerializer; +use crate::serde::ser::maps::MapSerializer; +use crate::serde::ser::sets::SetSerializer; +use crate::serde::ser::structs::StructSerializer; +use crate::serde::ser::tuple_structs::TupleStructSerializer; +use crate::serde::ser::tuples::TupleSerializer; +use crate::serde::Serializable; +use crate::{PartialReflect, ReflectRef, TypeRegistry}; +use serde::ser::{Error, SerializeMap}; +use serde::Serialize; + +/// A general purpose serializer for reflected types. +/// +/// This is the serializer counterpart to [`ReflectDeserializer`]. +/// +/// See [`TypedReflectSerializer`] for a serializer that serializes a known type. +/// +/// # Output +/// +/// This serializer will output a map with a single entry, +/// where the key is the _full_ [type path] of the reflected type +/// and the value is the serialized data. +/// +/// # Example +/// +/// ``` +/// # use bevy_reflect::prelude::*; +/// # use bevy_reflect::{TypeRegistry, serde::ReflectSerializer}; +/// #[derive(Reflect, PartialEq, Debug)] +/// #[type_path = "my_crate"] +/// struct MyStruct { +/// value: i32 +/// } +/// +/// let mut registry = TypeRegistry::default(); +/// registry.register::(); +/// +/// let input = MyStruct { value: 123 }; +/// +/// let reflect_serializer = ReflectSerializer::new(&input, ®istry); +/// let output = ron::to_string(&reflect_serializer).unwrap(); +/// +/// assert_eq!(output, r#"{"my_crate::MyStruct":(value:123)}"#); +/// ``` +/// +/// [`ReflectDeserializer`]: crate::serde::ReflectDeserializer +/// [type path]: crate::TypePath::type_path +pub struct ReflectSerializer<'a> { + value: &'a dyn PartialReflect, + registry: &'a TypeRegistry, +} + +impl<'a> ReflectSerializer<'a> { + pub fn new(value: &'a dyn PartialReflect, registry: &'a TypeRegistry) -> Self { + ReflectSerializer { value, registry } + } +} + +impl<'a> Serialize for ReflectSerializer<'a> { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_map(Some(1))?; + state.serialize_entry( + self.value + .get_represented_type_info() + .ok_or_else(|| { + if self.value.is_dynamic() { + Error::custom(format_args!( + "cannot serialize dynamic value without represented type: {}", + self.value.reflect_type_path() + )) + } else { + Error::custom(format_args!( + "cannot get type info for {}", + self.value.reflect_type_path() + )) + } + })? + .type_path(), + &TypedReflectSerializer::new(self.value, self.registry), + )?; + state.end() + } +} + +/// A serializer for reflected types whose type will be known during deserialization. +/// +/// This is the serializer counterpart to [`TypedReflectDeserializer`]. +/// +/// See [`ReflectSerializer`] for a serializer that serializes an unknown type. +/// +/// # Output +/// +/// Since the type is expected to be known during deserialization, +/// this serializer will not output any additional type information, +/// such as the [type path]. +/// +/// Instead, it will output just the serialized data. +/// +/// # Example +/// +/// ``` +/// # use bevy_reflect::prelude::*; +/// # use bevy_reflect::{TypeRegistry, serde::TypedReflectSerializer}; +/// #[derive(Reflect, PartialEq, Debug)] +/// #[type_path = "my_crate"] +/// struct MyStruct { +/// value: i32 +/// } +/// +/// let mut registry = TypeRegistry::default(); +/// registry.register::(); +/// +/// let input = MyStruct { value: 123 }; +/// +/// let reflect_serializer = TypedReflectSerializer::new(&input, ®istry); +/// let output = ron::to_string(&reflect_serializer).unwrap(); +/// +/// assert_eq!(output, r#"(value:123)"#); +/// ``` +/// +/// [`TypedReflectDeserializer`]: crate::serde::TypedReflectDeserializer +/// [type path]: crate::TypePath::type_path +pub struct TypedReflectSerializer<'a> { + value: &'a dyn PartialReflect, + registry: &'a TypeRegistry, +} + +impl<'a> TypedReflectSerializer<'a> { + pub fn new(value: &'a dyn PartialReflect, registry: &'a TypeRegistry) -> Self { + TypedReflectSerializer { value, registry } + } +} + +impl<'a> Serialize for TypedReflectSerializer<'a> { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + // Handle both Value case and types that have a custom `Serialize` + let serializable = + Serializable::try_from_reflect_value::(self.value, self.registry); + if let Ok(serializable) = serializable { + return serializable.serialize(serializer); + } + + match self.value.reflect_ref() { + ReflectRef::Struct(value) => { + StructSerializer::new(value, self.registry).serialize(serializer) + } + ReflectRef::TupleStruct(value) => { + TupleStructSerializer::new(value, self.registry).serialize(serializer) + } + ReflectRef::Tuple(value) => { + TupleSerializer::new(value, self.registry).serialize(serializer) + } + ReflectRef::List(value) => { + ListSerializer::new(value, self.registry).serialize(serializer) + } + ReflectRef::Array(value) => { + ArraySerializer::new(value, self.registry).serialize(serializer) + } + ReflectRef::Map(value) => { + MapSerializer::new(value, self.registry).serialize(serializer) + } + ReflectRef::Set(value) => { + SetSerializer::new(value, self.registry).serialize(serializer) + } + ReflectRef::Enum(value) => { + EnumSerializer::new(value, self.registry).serialize(serializer) + } + ReflectRef::Value(_) => Err(serializable.err().unwrap()), + } + } +} diff --git a/crates/bevy_reflect/src/serde/ser/sets.rs b/crates/bevy_reflect/src/serde/ser/sets.rs new file mode 100644 index 0000000000..9a5abab572 --- /dev/null +++ b/crates/bevy_reflect/src/serde/ser/sets.rs @@ -0,0 +1,29 @@ +use crate::serde::TypedReflectSerializer; +use crate::{Set, TypeRegistry}; +use serde::ser::SerializeSeq; +use serde::Serialize; + +/// A serializer for [`Set`] values. +pub(super) struct SetSerializer<'a> { + set: &'a dyn Set, + registry: &'a TypeRegistry, +} + +impl<'a> SetSerializer<'a> { + pub fn new(set: &'a dyn Set, registry: &'a TypeRegistry) -> Self { + Self { set, registry } + } +} + +impl<'a> Serialize for SetSerializer<'a> { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_seq(Some(self.set.len()))?; + for value in self.set.iter() { + state.serialize_element(&TypedReflectSerializer::new(value, self.registry))?; + } + state.end() + } +} diff --git a/crates/bevy_reflect/src/serde/ser/structs.rs b/crates/bevy_reflect/src/serde/ser/structs.rs new file mode 100644 index 0000000000..2c31280f05 --- /dev/null +++ b/crates/bevy_reflect/src/serde/ser/structs.rs @@ -0,0 +1,67 @@ +use crate::serde::{SerializationData, TypedReflectSerializer}; +use crate::{Struct, TypeInfo, TypeRegistry}; +use serde::ser::{Error, SerializeStruct}; +use serde::Serialize; + +/// A serializer for [`Struct`] values. +pub(super) struct StructSerializer<'a> { + struct_value: &'a dyn Struct, + registry: &'a TypeRegistry, +} + +impl<'a> StructSerializer<'a> { + pub fn new(struct_value: &'a dyn Struct, registry: &'a TypeRegistry) -> Self { + Self { + struct_value, + registry, + } + } +} + +impl<'a> Serialize for StructSerializer<'a> { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let type_info = self + .struct_value + .get_represented_type_info() + .ok_or_else(|| { + Error::custom(format_args!( + "cannot get type info for {}", + self.struct_value.reflect_type_path() + )) + })?; + + let struct_info = match type_info { + TypeInfo::Struct(struct_info) => struct_info, + info => { + return Err(Error::custom(format_args!( + "expected struct type but received {info:?}" + ))); + } + }; + + let serialization_data = self + .registry + .get(type_info.type_id()) + .and_then(|registration| registration.data::()); + let ignored_len = serialization_data.map(SerializationData::len).unwrap_or(0); + let mut state = serializer.serialize_struct( + struct_info.type_path_table().ident().unwrap(), + self.struct_value.field_len() - ignored_len, + )?; + + for (index, value) in self.struct_value.iter_fields().enumerate() { + if serialization_data + .map(|data| data.is_field_skipped(index)) + .unwrap_or(false) + { + continue; + } + let key = struct_info.field_at(index).unwrap().name(); + state.serialize_field(key, &TypedReflectSerializer::new(value, self.registry))?; + } + state.end() + } +} diff --git a/crates/bevy_reflect/src/serde/ser/tuple_structs.rs b/crates/bevy_reflect/src/serde/ser/tuple_structs.rs new file mode 100644 index 0000000000..e60c9ad66c --- /dev/null +++ b/crates/bevy_reflect/src/serde/ser/tuple_structs.rs @@ -0,0 +1,66 @@ +use crate::serde::{SerializationData, TypedReflectSerializer}; +use crate::{TupleStruct, TypeInfo, TypeRegistry}; +use serde::ser::{Error, SerializeTupleStruct}; +use serde::Serialize; + +/// A serializer for [`TupleStruct`] values. +pub(super) struct TupleStructSerializer<'a> { + tuple_struct: &'a dyn TupleStruct, + registry: &'a TypeRegistry, +} + +impl<'a> TupleStructSerializer<'a> { + pub fn new(tuple_struct: &'a dyn TupleStruct, registry: &'a TypeRegistry) -> Self { + Self { + tuple_struct, + registry, + } + } +} + +impl<'a> Serialize for TupleStructSerializer<'a> { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let type_info = self + .tuple_struct + .get_represented_type_info() + .ok_or_else(|| { + Error::custom(format_args!( + "cannot get type info for {}", + self.tuple_struct.reflect_type_path() + )) + })?; + + let tuple_struct_info = match type_info { + TypeInfo::TupleStruct(tuple_struct_info) => tuple_struct_info, + info => { + return Err(Error::custom(format_args!( + "expected tuple struct type but received {info:?}" + ))); + } + }; + + let serialization_data = self + .registry + .get(type_info.type_id()) + .and_then(|registration| registration.data::()); + let ignored_len = serialization_data.map(SerializationData::len).unwrap_or(0); + let mut state = serializer.serialize_tuple_struct( + tuple_struct_info.type_path_table().ident().unwrap(), + self.tuple_struct.field_len() - ignored_len, + )?; + + for (index, value) in self.tuple_struct.iter_fields().enumerate() { + if serialization_data + .map(|data| data.is_field_skipped(index)) + .unwrap_or(false) + { + continue; + } + state.serialize_field(&TypedReflectSerializer::new(value, self.registry))?; + } + state.end() + } +} diff --git a/crates/bevy_reflect/src/serde/ser/tuples.rs b/crates/bevy_reflect/src/serde/ser/tuples.rs new file mode 100644 index 0000000000..c3b90d5f56 --- /dev/null +++ b/crates/bevy_reflect/src/serde/ser/tuples.rs @@ -0,0 +1,30 @@ +use crate::serde::TypedReflectSerializer; +use crate::{Tuple, TypeRegistry}; +use serde::ser::SerializeTuple; +use serde::Serialize; + +/// A serializer for [`Tuple`] values. +pub(super) struct TupleSerializer<'a> { + tuple: &'a dyn Tuple, + registry: &'a TypeRegistry, +} + +impl<'a> TupleSerializer<'a> { + pub fn new(tuple: &'a dyn Tuple, registry: &'a TypeRegistry) -> Self { + Self { tuple, registry } + } +} + +impl<'a> Serialize for TupleSerializer<'a> { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_tuple(self.tuple.field_len())?; + + for value in self.tuple.iter_fields() { + state.serialize_element(&TypedReflectSerializer::new(value, self.registry))?; + } + state.end() + } +}