Path: blob/main/crates/bevy_reflect/src/serde/de/deserializer.rs
6849 views
#[cfg(feature = "debug_stack")]1use crate::serde::de::error_utils::TYPE_INFO_STACK;2use crate::serde::{ReflectDeserializeWithRegistry, SerializationData};3use crate::ReflectFromReflect;4use crate::{5serde::{6de::{7arrays::ArrayVisitor, enums::EnumVisitor, error_utils::make_custom_error,8lists::ListVisitor, maps::MapVisitor, options::OptionVisitor, sets::SetVisitor,9structs::StructVisitor, tuple_structs::TupleStructVisitor, tuples::TupleVisitor,10},11TypeRegistrationDeserializer,12},13PartialReflect, ReflectDeserialize, TypeInfo, TypePath, TypeRegistration, TypeRegistry,14};15use alloc::boxed::Box;16use core::{fmt, fmt::Formatter};17use serde::de::{DeserializeSeed, Error, IgnoredAny, MapAccess, Visitor};1819use super::ReflectDeserializerProcessor;2021/// A general purpose deserializer for reflected types.22///23/// This is the deserializer counterpart to [`ReflectSerializer`].24///25/// See [`TypedReflectDeserializer`] for a deserializer that expects a known type.26///27/// # Input28///29/// This deserializer expects a map with a single entry,30/// where the key is the _full_ [type path] of the reflected type31/// and the value is the serialized data.32///33/// # Output34///35/// This deserializer will return a [`Box<dyn Reflect>`] containing the deserialized data.36///37/// For opaque types (i.e. [`ReflectKind::Opaque`]) or types that register [`ReflectDeserialize`] type data,38/// this `Box` will contain the expected type.39/// For example, deserializing an `i32` will return a `Box<i32>` (as a `Box<dyn Reflect>`).40///41/// Otherwise, this `Box` will contain the dynamic equivalent.42/// For example, a deserialized struct might return a [`Box<DynamicStruct>`]43/// and a deserialized `Vec` might return a [`Box<DynamicList>`].44///45/// This means that if the actual type is needed, these dynamic representations will need to46/// be converted to the concrete type using [`FromReflect`] or [`ReflectFromReflect`].47///48/// If you want to override deserialization for a specific [`TypeRegistration`],49/// you can pass in a reference to a [`ReflectDeserializerProcessor`] which will50/// take priority over all other deserialization methods - see [`with_processor`].51///52/// # Example53///54/// ```55/// # use serde::de::DeserializeSeed;56/// # use bevy_reflect::prelude::*;57/// # use bevy_reflect::{DynamicStruct, TypeRegistry, serde::ReflectDeserializer};58/// #[derive(Reflect, PartialEq, Debug)]59/// #[type_path = "my_crate"]60/// struct MyStruct {61/// value: i3262/// }63///64/// let mut registry = TypeRegistry::default();65/// registry.register::<MyStruct>();66///67/// let input = r#"{68/// "my_crate::MyStruct": (69/// value: 12370/// )71/// }"#;72///73/// let mut deserializer = ron::Deserializer::from_str(input).unwrap();74/// let reflect_deserializer = ReflectDeserializer::new(®istry);75///76/// let output: Box<dyn PartialReflect> = reflect_deserializer.deserialize(&mut deserializer).unwrap();77///78/// // Since `MyStruct` is not an opaque type and does not register `ReflectDeserialize`,79/// // we know that its deserialized value will be a `DynamicStruct`,80/// // although it will represent `MyStruct`.81/// assert!(output.as_partial_reflect().represents::<MyStruct>());82///83/// // We can convert back to `MyStruct` using `FromReflect`.84/// let value: MyStruct = <MyStruct as FromReflect>::from_reflect(output.as_partial_reflect()).unwrap();85/// assert_eq!(value, MyStruct { value: 123 });86///87/// // We can also do this dynamically with `ReflectFromReflect`.88/// let type_id = output.get_represented_type_info().unwrap().type_id();89/// let reflect_from_reflect = registry.get_type_data::<ReflectFromReflect>(type_id).unwrap();90/// let value: Box<dyn Reflect> = reflect_from_reflect.from_reflect(output.as_partial_reflect()).unwrap();91/// assert!(value.is::<MyStruct>());92/// assert_eq!(value.take::<MyStruct>().unwrap(), MyStruct { value: 123 });93/// ```94///95/// [`ReflectSerializer`]: crate::serde::ReflectSerializer96/// [type path]: crate::TypePath::type_path97/// [`Box<dyn Reflect>`]: crate::Reflect98/// [`ReflectKind::Opaque`]: crate::ReflectKind::Opaque99/// [`ReflectDeserialize`]: crate::ReflectDeserialize100/// [`Box<DynamicStruct>`]: crate::DynamicStruct101/// [`Box<DynamicList>`]: crate::DynamicList102/// [`FromReflect`]: crate::FromReflect103/// [`ReflectFromReflect`]: crate::ReflectFromReflect104/// [`with_processor`]: Self::with_processor105pub struct ReflectDeserializer<'a, P: ReflectDeserializerProcessor = ()> {106registry: &'a TypeRegistry,107processor: Option<&'a mut P>,108}109110impl<'a> ReflectDeserializer<'a, ()> {111/// Creates a deserializer with no processor.112///113/// If you want to add custom logic for deserializing certain types, use114/// [`with_processor`].115///116/// [`with_processor`]: Self::with_processor117pub fn new(registry: &'a TypeRegistry) -> Self {118Self {119registry,120processor: None,121}122}123}124125impl<'a, P: ReflectDeserializerProcessor> ReflectDeserializer<'a, P> {126/// Creates a deserializer with a processor.127///128/// If you do not need any custom logic for handling certain types, use129/// [`new`].130///131/// [`new`]: Self::new132pub fn with_processor(registry: &'a TypeRegistry, processor: &'a mut P) -> Self {133Self {134registry,135processor: Some(processor),136}137}138}139140impl<'de, P: ReflectDeserializerProcessor> DeserializeSeed<'de> for ReflectDeserializer<'_, P> {141type Value = Box<dyn PartialReflect>;142143fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>144where145D: serde::Deserializer<'de>,146{147struct UntypedReflectDeserializerVisitor<'a, P> {148registry: &'a TypeRegistry,149processor: Option<&'a mut P>,150}151152impl<'de, P: ReflectDeserializerProcessor> Visitor<'de>153for UntypedReflectDeserializerVisitor<'_, P>154{155type Value = Box<dyn PartialReflect>;156157fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {158formatter159.write_str("map containing `type` and `value` entries for the reflected value")160}161162fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>163where164A: MapAccess<'de>,165{166let registration = map167.next_key_seed(TypeRegistrationDeserializer::new(self.registry))?168.ok_or_else(|| Error::invalid_length(0, &"a single entry"))?;169170let value = map.next_value_seed(TypedReflectDeserializer::new_internal(171registration,172self.registry,173self.processor,174))?;175176if map.next_key::<IgnoredAny>()?.is_some() {177return Err(Error::invalid_length(2, &"a single entry"));178}179180Ok(value)181}182}183184deserializer.deserialize_map(UntypedReflectDeserializerVisitor {185registry: self.registry,186processor: self.processor,187})188}189}190191/// A deserializer for reflected types whose [`TypeRegistration`] is known.192///193/// This is the deserializer counterpart to [`TypedReflectSerializer`].194///195/// See [`ReflectDeserializer`] for a deserializer that expects an unknown type.196///197/// # Input198///199/// Since the type is already known, the input is just the serialized data.200///201/// # Output202///203/// This deserializer will return a [`Box<dyn Reflect>`] containing the deserialized data.204///205/// For opaque types (i.e. [`ReflectKind::Opaque`]) or types that register [`ReflectDeserialize`] type data,206/// this `Box` will contain the expected type.207/// For example, deserializing an `i32` will return a `Box<i32>` (as a `Box<dyn Reflect>`).208///209/// Otherwise, this `Box` will contain the dynamic equivalent.210/// For example, a deserialized struct might return a [`Box<DynamicStruct>`]211/// and a deserialized `Vec` might return a [`Box<DynamicList>`].212///213/// This means that if the actual type is needed, these dynamic representations will need to214/// be converted to the concrete type using [`FromReflect`] or [`ReflectFromReflect`].215///216/// If you want to override deserialization for a specific [`TypeRegistration`],217/// you can pass in a reference to a [`ReflectDeserializerProcessor`] which will218/// take priority over all other deserialization methods - see [`with_processor`].219///220/// # Example221///222/// ```223/// # use core::any::TypeId;224/// # use serde::de::DeserializeSeed;225/// # use bevy_reflect::prelude::*;226/// # use bevy_reflect::{DynamicStruct, TypeRegistry, serde::TypedReflectDeserializer};227/// #[derive(Reflect, PartialEq, Debug)]228/// struct MyStruct {229/// value: i32230/// }231///232/// let mut registry = TypeRegistry::default();233/// registry.register::<MyStruct>();234///235/// let input = r#"(236/// value: 123237/// )"#;238///239/// let registration = registry.get(TypeId::of::<MyStruct>()).unwrap();240///241/// let mut deserializer = ron::Deserializer::from_str(input).unwrap();242/// let reflect_deserializer = TypedReflectDeserializer::new(registration, ®istry);243///244/// let output: Box<dyn PartialReflect> = reflect_deserializer.deserialize(&mut deserializer).unwrap();245///246/// // Since `MyStruct` is not an opaque type and does not register `ReflectDeserialize`,247/// // we know that its deserialized value will be a `DynamicStruct`,248/// // although it will represent `MyStruct`.249/// assert!(output.as_partial_reflect().represents::<MyStruct>());250///251/// // We can convert back to `MyStruct` using `FromReflect`.252/// let value: MyStruct = <MyStruct as FromReflect>::from_reflect(output.as_partial_reflect()).unwrap();253/// assert_eq!(value, MyStruct { value: 123 });254///255/// // We can also do this dynamically with `ReflectFromReflect`.256/// let type_id = output.get_represented_type_info().unwrap().type_id();257/// let reflect_from_reflect = registry.get_type_data::<ReflectFromReflect>(type_id).unwrap();258/// let value: Box<dyn Reflect> = reflect_from_reflect.from_reflect(output.as_partial_reflect()).unwrap();259/// assert!(value.is::<MyStruct>());260/// assert_eq!(value.take::<MyStruct>().unwrap(), MyStruct { value: 123 });261/// ```262///263/// [`TypedReflectSerializer`]: crate::serde::TypedReflectSerializer264/// [`Box<dyn Reflect>`]: crate::Reflect265/// [`ReflectKind::Opaque`]: crate::ReflectKind::Opaque266/// [`ReflectDeserialize`]: crate::ReflectDeserialize267/// [`Box<DynamicStruct>`]: crate::DynamicStruct268/// [`Box<DynamicList>`]: crate::DynamicList269/// [`FromReflect`]: crate::FromReflect270/// [`ReflectFromReflect`]: crate::ReflectFromReflect271/// [`with_processor`]: Self::with_processor272pub struct TypedReflectDeserializer<'a, P: ReflectDeserializerProcessor = ()> {273registration: &'a TypeRegistration,274registry: &'a TypeRegistry,275processor: Option<&'a mut P>,276}277278impl<'a> TypedReflectDeserializer<'a, ()> {279/// Creates a typed deserializer with no processor.280///281/// If you want to add custom logic for deserializing certain types, use282/// [`with_processor`].283///284/// [`with_processor`]: Self::with_processor285pub fn new(registration: &'a TypeRegistration, registry: &'a TypeRegistry) -> Self {286#[cfg(feature = "debug_stack")]287TYPE_INFO_STACK.set(crate::type_info_stack::TypeInfoStack::new());288289Self {290registration,291registry,292processor: None,293}294}295296/// Creates a new [`TypedReflectDeserializer`] for the given type `T`297/// without a processor.298///299/// # Panics300///301/// Panics if `T` is not registered in the given [`TypeRegistry`].302pub fn of<T: TypePath>(registry: &'a TypeRegistry) -> Self {303let registration = registry304.get(core::any::TypeId::of::<T>())305.unwrap_or_else(|| panic!("no registration found for type `{}`", T::type_path()));306307Self {308registration,309registry,310processor: None,311}312}313}314315impl<'a, P: ReflectDeserializerProcessor> TypedReflectDeserializer<'a, P> {316/// Creates a typed deserializer with a processor.317///318/// If you do not need any custom logic for handling certain types, use319/// [`new`].320///321/// [`new`]: Self::new322pub fn with_processor(323registration: &'a TypeRegistration,324registry: &'a TypeRegistry,325processor: &'a mut P,326) -> Self {327#[cfg(feature = "debug_stack")]328TYPE_INFO_STACK.set(crate::type_info_stack::TypeInfoStack::new());329330Self {331registration,332registry,333processor: Some(processor),334}335}336337/// An internal constructor for creating a deserializer without resetting the type info stack.338pub(super) fn new_internal(339registration: &'a TypeRegistration,340registry: &'a TypeRegistry,341processor: Option<&'a mut P>,342) -> Self {343Self {344registration,345registry,346processor,347}348}349}350351impl<'de, P: ReflectDeserializerProcessor> DeserializeSeed<'de>352for TypedReflectDeserializer<'_, P>353{354type Value = Box<dyn PartialReflect>;355356fn deserialize<D>(mut self, deserializer: D) -> Result<Self::Value, D::Error>357where358D: serde::Deserializer<'de>,359{360let deserialize_internal = || -> Result<Self::Value, D::Error> {361// First, check if our processor wants to deserialize this type362// This takes priority over any other deserialization operations363let deserializer = if let Some(processor) = self.processor.as_deref_mut() {364match processor.try_deserialize(self.registration, self.registry, deserializer) {365Ok(Ok(value)) => {366return Ok(value);367}368Err(err) => {369return Err(make_custom_error(err));370}371Ok(Err(deserializer)) => deserializer,372}373} else {374deserializer375};376377let type_path = self.registration.type_info().type_path();378379// Handle both Value case and types that have a custom `ReflectDeserialize`380if let Some(deserialize_reflect) = self.registration.data::<ReflectDeserialize>() {381let value = deserialize_reflect.deserialize(deserializer)?;382return Ok(value.into_partial_reflect());383}384385if let Some(deserialize_reflect) =386self.registration.data::<ReflectDeserializeWithRegistry>()387{388let value = deserialize_reflect.deserialize(deserializer, self.registry)?;389return Ok(value);390}391392let dynamic_value: Box<dyn PartialReflect> = match self.registration.type_info() {393TypeInfo::Struct(struct_info) => {394let mut dynamic_struct = deserializer.deserialize_struct(395struct_info.type_path_table().ident().unwrap(),396struct_info.field_names(),397StructVisitor {398struct_info,399registration: self.registration,400registry: self.registry,401processor: self.processor,402},403)?;404dynamic_struct.set_represented_type(Some(self.registration.type_info()));405Box::new(dynamic_struct)406}407TypeInfo::TupleStruct(tuple_struct_info) => {408let mut dynamic_tuple_struct = if tuple_struct_info.field_len() == 1409&& self.registration.data::<SerializationData>().is_none()410{411deserializer.deserialize_newtype_struct(412tuple_struct_info.type_path_table().ident().unwrap(),413TupleStructVisitor {414tuple_struct_info,415registration: self.registration,416registry: self.registry,417processor: self.processor,418},419)?420} else {421deserializer.deserialize_tuple_struct(422tuple_struct_info.type_path_table().ident().unwrap(),423tuple_struct_info.field_len(),424TupleStructVisitor {425tuple_struct_info,426registration: self.registration,427registry: self.registry,428processor: self.processor,429},430)?431};432dynamic_tuple_struct.set_represented_type(Some(self.registration.type_info()));433Box::new(dynamic_tuple_struct)434}435TypeInfo::List(list_info) => {436let mut dynamic_list = deserializer.deserialize_seq(ListVisitor {437list_info,438registry: self.registry,439processor: self.processor,440})?;441dynamic_list.set_represented_type(Some(self.registration.type_info()));442Box::new(dynamic_list)443}444TypeInfo::Array(array_info) => {445let mut dynamic_array = deserializer.deserialize_tuple(446array_info.capacity(),447ArrayVisitor {448array_info,449registry: self.registry,450processor: self.processor,451},452)?;453dynamic_array.set_represented_type(Some(self.registration.type_info()));454Box::new(dynamic_array)455}456TypeInfo::Map(map_info) => {457let mut dynamic_map = deserializer.deserialize_map(MapVisitor {458map_info,459registry: self.registry,460processor: self.processor,461})?;462dynamic_map.set_represented_type(Some(self.registration.type_info()));463Box::new(dynamic_map)464}465TypeInfo::Set(set_info) => {466let mut dynamic_set = deserializer.deserialize_seq(SetVisitor {467set_info,468registry: self.registry,469processor: self.processor,470})?;471dynamic_set.set_represented_type(Some(self.registration.type_info()));472Box::new(dynamic_set)473}474TypeInfo::Tuple(tuple_info) => {475let mut dynamic_tuple = deserializer.deserialize_tuple(476tuple_info.field_len(),477TupleVisitor {478tuple_info,479registration: self.registration,480registry: self.registry,481processor: self.processor,482},483)?;484dynamic_tuple.set_represented_type(Some(self.registration.type_info()));485Box::new(dynamic_tuple)486}487TypeInfo::Enum(enum_info) => {488let mut dynamic_enum = if enum_info.type_path_table().module_path()489== Some("core::option")490&& enum_info.type_path_table().ident() == Some("Option")491{492deserializer.deserialize_option(OptionVisitor {493enum_info,494registry: self.registry,495processor: self.processor,496})?497} else {498deserializer.deserialize_enum(499enum_info.type_path_table().ident().unwrap(),500enum_info.variant_names(),501EnumVisitor {502enum_info,503registration: self.registration,504registry: self.registry,505processor: self.processor,506},507)?508};509dynamic_enum.set_represented_type(Some(self.registration.type_info()));510Box::new(dynamic_enum)511}512TypeInfo::Opaque(_) => {513// This case should already be handled514return Err(make_custom_error(format_args!(515"type `{type_path}` did not register the `ReflectDeserialize` type data. For certain types, this may need to be registered manually using `register_type_data`",516)));517}518};519520// Try to produce a concrete instance of the type to deserialize by using the reflected `FromReflect`.521if let Some(from_reflect) = self.registration.data::<ReflectFromReflect>()522&& let Some(value) = from_reflect.from_reflect(&*dynamic_value)523{524return Ok(value);525}526527Ok(dynamic_value)528};529530#[cfg(feature = "debug_stack")]531TYPE_INFO_STACK.with_borrow_mut(|stack| stack.push(self.registration.type_info()));532533let output = deserialize_internal();534535#[cfg(feature = "debug_stack")]536TYPE_INFO_STACK.with_borrow_mut(crate::type_info_stack::TypeInfoStack::pop);537538output539}540}541542543