Path: blob/main/crates/bevy_reflect/src/serde/de/deserializer.rs
6600 views
#[cfg(feature = "debug_stack")]1use crate::serde::de::error_utils::TYPE_INFO_STACK;2use crate::serde::{ReflectDeserializeWithRegistry, SerializationData};3use crate::{4serde::{5de::{6arrays::ArrayVisitor, enums::EnumVisitor, error_utils::make_custom_error,7lists::ListVisitor, maps::MapVisitor, options::OptionVisitor, sets::SetVisitor,8structs::StructVisitor, tuple_structs::TupleStructVisitor, tuples::TupleVisitor,9},10TypeRegistrationDeserializer,11},12PartialReflect, ReflectDeserialize, TypeInfo, TypePath, TypeRegistration, TypeRegistry,13};14use alloc::boxed::Box;15use core::{fmt, fmt::Formatter};16use serde::de::{DeserializeSeed, Error, IgnoredAny, MapAccess, Visitor};1718use super::ReflectDeserializerProcessor;1920/// A general purpose deserializer for reflected types.21///22/// This is the deserializer counterpart to [`ReflectSerializer`].23///24/// See [`TypedReflectDeserializer`] for a deserializer that expects a known type.25///26/// # Input27///28/// This deserializer expects a map with a single entry,29/// where the key is the _full_ [type path] of the reflected type30/// and the value is the serialized data.31///32/// # Output33///34/// This deserializer will return a [`Box<dyn Reflect>`] containing the deserialized data.35///36/// For opaque types (i.e. [`ReflectKind::Opaque`]) or types that register [`ReflectDeserialize`] type data,37/// this `Box` will contain the expected type.38/// For example, deserializing an `i32` will return a `Box<i32>` (as a `Box<dyn Reflect>`).39///40/// Otherwise, this `Box` will contain the dynamic equivalent.41/// For example, a deserialized struct might return a [`Box<DynamicStruct>`]42/// and a deserialized `Vec` might return a [`Box<DynamicList>`].43///44/// This means that if the actual type is needed, these dynamic representations will need to45/// be converted to the concrete type using [`FromReflect`] or [`ReflectFromReflect`].46///47/// If you want to override deserialization for a specific [`TypeRegistration`],48/// you can pass in a reference to a [`ReflectDeserializerProcessor`] which will49/// take priority over all other deserialization methods - see [`with_processor`].50///51/// # Example52///53/// ```54/// # use serde::de::DeserializeSeed;55/// # use bevy_reflect::prelude::*;56/// # use bevy_reflect::{DynamicStruct, TypeRegistry, serde::ReflectDeserializer};57/// #[derive(Reflect, PartialEq, Debug)]58/// #[type_path = "my_crate"]59/// struct MyStruct {60/// value: i3261/// }62///63/// let mut registry = TypeRegistry::default();64/// registry.register::<MyStruct>();65///66/// let input = r#"{67/// "my_crate::MyStruct": (68/// value: 12369/// )70/// }"#;71///72/// let mut deserializer = ron::Deserializer::from_str(input).unwrap();73/// let reflect_deserializer = ReflectDeserializer::new(®istry);74///75/// let output: Box<dyn PartialReflect> = reflect_deserializer.deserialize(&mut deserializer).unwrap();76///77/// // Since `MyStruct` is not an opaque type and does not register `ReflectDeserialize`,78/// // we know that its deserialized value will be a `DynamicStruct`,79/// // although it will represent `MyStruct`.80/// assert!(output.as_partial_reflect().represents::<MyStruct>());81///82/// // We can convert back to `MyStruct` using `FromReflect`.83/// let value: MyStruct = <MyStruct as FromReflect>::from_reflect(output.as_partial_reflect()).unwrap();84/// assert_eq!(value, MyStruct { value: 123 });85///86/// // We can also do this dynamically with `ReflectFromReflect`.87/// let type_id = output.get_represented_type_info().unwrap().type_id();88/// let reflect_from_reflect = registry.get_type_data::<ReflectFromReflect>(type_id).unwrap();89/// let value: Box<dyn Reflect> = reflect_from_reflect.from_reflect(output.as_partial_reflect()).unwrap();90/// assert!(value.is::<MyStruct>());91/// assert_eq!(value.take::<MyStruct>().unwrap(), MyStruct { value: 123 });92/// ```93///94/// [`ReflectSerializer`]: crate::serde::ReflectSerializer95/// [type path]: crate::TypePath::type_path96/// [`Box<dyn Reflect>`]: crate::Reflect97/// [`ReflectKind::Opaque`]: crate::ReflectKind::Opaque98/// [`ReflectDeserialize`]: crate::ReflectDeserialize99/// [`Box<DynamicStruct>`]: crate::DynamicStruct100/// [`Box<DynamicList>`]: crate::DynamicList101/// [`FromReflect`]: crate::FromReflect102/// [`ReflectFromReflect`]: crate::ReflectFromReflect103/// [`with_processor`]: Self::with_processor104pub struct ReflectDeserializer<'a, P: ReflectDeserializerProcessor = ()> {105registry: &'a TypeRegistry,106processor: Option<&'a mut P>,107}108109impl<'a> ReflectDeserializer<'a, ()> {110/// Creates a deserializer with no processor.111///112/// If you want to add custom logic for deserializing certain types, use113/// [`with_processor`].114///115/// [`with_processor`]: Self::with_processor116pub fn new(registry: &'a TypeRegistry) -> Self {117Self {118registry,119processor: None,120}121}122}123124impl<'a, P: ReflectDeserializerProcessor> ReflectDeserializer<'a, P> {125/// Creates a deserializer with a processor.126///127/// If you do not need any custom logic for handling certain types, use128/// [`new`].129///130/// [`new`]: Self::new131pub fn with_processor(registry: &'a TypeRegistry, processor: &'a mut P) -> Self {132Self {133registry,134processor: Some(processor),135}136}137}138139impl<'de, P: ReflectDeserializerProcessor> DeserializeSeed<'de> for ReflectDeserializer<'_, P> {140type Value = Box<dyn PartialReflect>;141142fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>143where144D: serde::Deserializer<'de>,145{146struct UntypedReflectDeserializerVisitor<'a, P> {147registry: &'a TypeRegistry,148processor: Option<&'a mut P>,149}150151impl<'de, P: ReflectDeserializerProcessor> Visitor<'de>152for UntypedReflectDeserializerVisitor<'_, P>153{154type Value = Box<dyn PartialReflect>;155156fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {157formatter158.write_str("map containing `type` and `value` entries for the reflected value")159}160161fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>162where163A: MapAccess<'de>,164{165let registration = map166.next_key_seed(TypeRegistrationDeserializer::new(self.registry))?167.ok_or_else(|| Error::invalid_length(0, &"a single entry"))?;168169let value = map.next_value_seed(TypedReflectDeserializer::new_internal(170registration,171self.registry,172self.processor,173))?;174175if map.next_key::<IgnoredAny>()?.is_some() {176return Err(Error::invalid_length(2, &"a single entry"));177}178179Ok(value)180}181}182183deserializer.deserialize_map(UntypedReflectDeserializerVisitor {184registry: self.registry,185processor: self.processor,186})187}188}189190/// A deserializer for reflected types whose [`TypeRegistration`] is known.191///192/// This is the deserializer counterpart to [`TypedReflectSerializer`].193///194/// See [`ReflectDeserializer`] for a deserializer that expects an unknown type.195///196/// # Input197///198/// Since the type is already known, the input is just the serialized data.199///200/// # Output201///202/// This deserializer will return a [`Box<dyn Reflect>`] containing the deserialized data.203///204/// For opaque types (i.e. [`ReflectKind::Opaque`]) or types that register [`ReflectDeserialize`] type data,205/// this `Box` will contain the expected type.206/// For example, deserializing an `i32` will return a `Box<i32>` (as a `Box<dyn Reflect>`).207///208/// Otherwise, this `Box` will contain the dynamic equivalent.209/// For example, a deserialized struct might return a [`Box<DynamicStruct>`]210/// and a deserialized `Vec` might return a [`Box<DynamicList>`].211///212/// This means that if the actual type is needed, these dynamic representations will need to213/// be converted to the concrete type using [`FromReflect`] or [`ReflectFromReflect`].214///215/// If you want to override deserialization for a specific [`TypeRegistration`],216/// you can pass in a reference to a [`ReflectDeserializerProcessor`] which will217/// take priority over all other deserialization methods - see [`with_processor`].218///219/// # Example220///221/// ```222/// # use core::any::TypeId;223/// # use serde::de::DeserializeSeed;224/// # use bevy_reflect::prelude::*;225/// # use bevy_reflect::{DynamicStruct, TypeRegistry, serde::TypedReflectDeserializer};226/// #[derive(Reflect, PartialEq, Debug)]227/// struct MyStruct {228/// value: i32229/// }230///231/// let mut registry = TypeRegistry::default();232/// registry.register::<MyStruct>();233///234/// let input = r#"(235/// value: 123236/// )"#;237///238/// let registration = registry.get(TypeId::of::<MyStruct>()).unwrap();239///240/// let mut deserializer = ron::Deserializer::from_str(input).unwrap();241/// let reflect_deserializer = TypedReflectDeserializer::new(registration, ®istry);242///243/// let output: Box<dyn PartialReflect> = reflect_deserializer.deserialize(&mut deserializer).unwrap();244///245/// // Since `MyStruct` is not an opaque type and does not register `ReflectDeserialize`,246/// // we know that its deserialized value will be a `DynamicStruct`,247/// // although it will represent `MyStruct`.248/// assert!(output.as_partial_reflect().represents::<MyStruct>());249///250/// // We can convert back to `MyStruct` using `FromReflect`.251/// let value: MyStruct = <MyStruct as FromReflect>::from_reflect(output.as_partial_reflect()).unwrap();252/// assert_eq!(value, MyStruct { value: 123 });253///254/// // We can also do this dynamically with `ReflectFromReflect`.255/// let type_id = output.get_represented_type_info().unwrap().type_id();256/// let reflect_from_reflect = registry.get_type_data::<ReflectFromReflect>(type_id).unwrap();257/// let value: Box<dyn Reflect> = reflect_from_reflect.from_reflect(output.as_partial_reflect()).unwrap();258/// assert!(value.is::<MyStruct>());259/// assert_eq!(value.take::<MyStruct>().unwrap(), MyStruct { value: 123 });260/// ```261///262/// [`TypedReflectSerializer`]: crate::serde::TypedReflectSerializer263/// [`Box<dyn Reflect>`]: crate::Reflect264/// [`ReflectKind::Opaque`]: crate::ReflectKind::Opaque265/// [`ReflectDeserialize`]: crate::ReflectDeserialize266/// [`Box<DynamicStruct>`]: crate::DynamicStruct267/// [`Box<DynamicList>`]: crate::DynamicList268/// [`FromReflect`]: crate::FromReflect269/// [`ReflectFromReflect`]: crate::ReflectFromReflect270/// [`with_processor`]: Self::with_processor271pub struct TypedReflectDeserializer<'a, P: ReflectDeserializerProcessor = ()> {272registration: &'a TypeRegistration,273registry: &'a TypeRegistry,274processor: Option<&'a mut P>,275}276277impl<'a> TypedReflectDeserializer<'a, ()> {278/// Creates a typed deserializer with no processor.279///280/// If you want to add custom logic for deserializing certain types, use281/// [`with_processor`].282///283/// [`with_processor`]: Self::with_processor284pub fn new(registration: &'a TypeRegistration, registry: &'a TypeRegistry) -> Self {285#[cfg(feature = "debug_stack")]286TYPE_INFO_STACK.set(crate::type_info_stack::TypeInfoStack::new());287288Self {289registration,290registry,291processor: None,292}293}294295/// Creates a new [`TypedReflectDeserializer`] for the given type `T`296/// without a processor.297///298/// # Panics299///300/// Panics if `T` is not registered in the given [`TypeRegistry`].301pub fn of<T: TypePath>(registry: &'a TypeRegistry) -> Self {302let registration = registry303.get(core::any::TypeId::of::<T>())304.unwrap_or_else(|| panic!("no registration found for type `{}`", T::type_path()));305306Self {307registration,308registry,309processor: None,310}311}312}313314impl<'a, P: ReflectDeserializerProcessor> TypedReflectDeserializer<'a, P> {315/// Creates a typed deserializer with a processor.316///317/// If you do not need any custom logic for handling certain types, use318/// [`new`].319///320/// [`new`]: Self::new321pub fn with_processor(322registration: &'a TypeRegistration,323registry: &'a TypeRegistry,324processor: &'a mut P,325) -> Self {326#[cfg(feature = "debug_stack")]327TYPE_INFO_STACK.set(crate::type_info_stack::TypeInfoStack::new());328329Self {330registration,331registry,332processor: Some(processor),333}334}335336/// An internal constructor for creating a deserializer without resetting the type info stack.337pub(super) fn new_internal(338registration: &'a TypeRegistration,339registry: &'a TypeRegistry,340processor: Option<&'a mut P>,341) -> Self {342Self {343registration,344registry,345processor,346}347}348}349350impl<'de, P: ReflectDeserializerProcessor> DeserializeSeed<'de>351for TypedReflectDeserializer<'_, P>352{353type Value = Box<dyn PartialReflect>;354355fn deserialize<D>(mut self, deserializer: D) -> Result<Self::Value, D::Error>356where357D: serde::Deserializer<'de>,358{359let deserialize_internal = || -> Result<Self::Value, D::Error> {360// First, check if our processor wants to deserialize this type361// This takes priority over any other deserialization operations362let deserializer = if let Some(processor) = self.processor.as_deref_mut() {363match processor.try_deserialize(self.registration, self.registry, deserializer) {364Ok(Ok(value)) => {365return Ok(value);366}367Err(err) => {368return Err(make_custom_error(err));369}370Ok(Err(deserializer)) => deserializer,371}372} else {373deserializer374};375376let type_path = self.registration.type_info().type_path();377378// Handle both Value case and types that have a custom `ReflectDeserialize`379if let Some(deserialize_reflect) = self.registration.data::<ReflectDeserialize>() {380let value = deserialize_reflect.deserialize(deserializer)?;381return Ok(value.into_partial_reflect());382}383384if let Some(deserialize_reflect) =385self.registration.data::<ReflectDeserializeWithRegistry>()386{387let value = deserialize_reflect.deserialize(deserializer, self.registry)?;388return Ok(value);389}390391match self.registration.type_info() {392TypeInfo::Struct(struct_info) => {393let mut dynamic_struct = deserializer.deserialize_struct(394struct_info.type_path_table().ident().unwrap(),395struct_info.field_names(),396StructVisitor {397struct_info,398registration: self.registration,399registry: self.registry,400processor: self.processor,401},402)?;403dynamic_struct.set_represented_type(Some(self.registration.type_info()));404Ok(Box::new(dynamic_struct))405}406TypeInfo::TupleStruct(tuple_struct_info) => {407let mut dynamic_tuple_struct = if tuple_struct_info.field_len() == 1408&& self.registration.data::<SerializationData>().is_none()409{410deserializer.deserialize_newtype_struct(411tuple_struct_info.type_path_table().ident().unwrap(),412TupleStructVisitor {413tuple_struct_info,414registration: self.registration,415registry: self.registry,416processor: self.processor,417},418)?419} else {420deserializer.deserialize_tuple_struct(421tuple_struct_info.type_path_table().ident().unwrap(),422tuple_struct_info.field_len(),423TupleStructVisitor {424tuple_struct_info,425registration: self.registration,426registry: self.registry,427processor: self.processor,428},429)?430};431dynamic_tuple_struct.set_represented_type(Some(self.registration.type_info()));432Ok(Box::new(dynamic_tuple_struct))433}434TypeInfo::List(list_info) => {435let mut dynamic_list = deserializer.deserialize_seq(ListVisitor {436list_info,437registry: self.registry,438processor: self.processor,439})?;440dynamic_list.set_represented_type(Some(self.registration.type_info()));441Ok(Box::new(dynamic_list))442}443TypeInfo::Array(array_info) => {444let mut dynamic_array = deserializer.deserialize_tuple(445array_info.capacity(),446ArrayVisitor {447array_info,448registry: self.registry,449processor: self.processor,450},451)?;452dynamic_array.set_represented_type(Some(self.registration.type_info()));453Ok(Box::new(dynamic_array))454}455TypeInfo::Map(map_info) => {456let mut dynamic_map = deserializer.deserialize_map(MapVisitor {457map_info,458registry: self.registry,459processor: self.processor,460})?;461dynamic_map.set_represented_type(Some(self.registration.type_info()));462Ok(Box::new(dynamic_map))463}464TypeInfo::Set(set_info) => {465let mut dynamic_set = deserializer.deserialize_seq(SetVisitor {466set_info,467registry: self.registry,468processor: self.processor,469})?;470dynamic_set.set_represented_type(Some(self.registration.type_info()));471Ok(Box::new(dynamic_set))472}473TypeInfo::Tuple(tuple_info) => {474let mut dynamic_tuple = deserializer.deserialize_tuple(475tuple_info.field_len(),476TupleVisitor {477tuple_info,478registration: self.registration,479registry: self.registry,480processor: self.processor,481},482)?;483dynamic_tuple.set_represented_type(Some(self.registration.type_info()));484Ok(Box::new(dynamic_tuple))485}486TypeInfo::Enum(enum_info) => {487let mut dynamic_enum = if enum_info.type_path_table().module_path()488== Some("core::option")489&& enum_info.type_path_table().ident() == Some("Option")490{491deserializer.deserialize_option(OptionVisitor {492enum_info,493registry: self.registry,494processor: self.processor,495})?496} else {497deserializer.deserialize_enum(498enum_info.type_path_table().ident().unwrap(),499enum_info.variant_names(),500EnumVisitor {501enum_info,502registration: self.registration,503registry: self.registry,504processor: self.processor,505},506)?507};508dynamic_enum.set_represented_type(Some(self.registration.type_info()));509Ok(Box::new(dynamic_enum))510}511TypeInfo::Opaque(_) => {512// This case should already be handled513Err(make_custom_error(format_args!(514"type `{type_path}` did not register the `ReflectDeserialize` type data. For certain types, this may need to be registered manually using `register_type_data`",515)))516}517}518};519520#[cfg(feature = "debug_stack")]521TYPE_INFO_STACK.with_borrow_mut(|stack| stack.push(self.registration.type_info()));522523let output = deserialize_internal();524525#[cfg(feature = "debug_stack")]526TYPE_INFO_STACK.with_borrow_mut(crate::type_info_stack::TypeInfoStack::pop);527528output529}530}531532533