Path: blob/main/crates/bevy_reflect/src/serde/de/deserialize_with_registry.rs
6600 views
use crate::serde::de::error_utils::make_custom_error;1use crate::{FromType, PartialReflect, TypeRegistry};2use alloc::boxed::Box;3use serde::Deserializer;45/// Trait used to provide finer control when deserializing a reflected type with one of6/// the reflection deserializers.7///8/// This trait is the reflection equivalent of `serde`'s [`Deserialize`] trait.9/// The main difference is that this trait provides access to the [`TypeRegistry`],10/// which means that we can use the registry and all its stored type information11/// to deserialize our type.12///13/// This can be useful when writing a custom reflection deserializer where we may14/// want to handle parts of the deserialization process, but temporarily pass control15/// to the standard reflection deserializer for other parts.16///17/// For the serialization equivalent of this trait, see [`SerializeWithRegistry`].18///19/// # Rationale20///21/// Without this trait and its associated [type data], such a deserializer would have to22/// write out all of the deserialization logic itself, possibly including23/// unnecessary code duplication and trivial implementations.24///25/// This is because a normal [`Deserialize`] implementation has no knowledge of the26/// [`TypeRegistry`] and therefore cannot create a reflection-based deserializer for27/// nested items.28///29/// # Implementors30///31/// In order for this to work with the reflection deserializers like [`TypedReflectDeserializer`]32/// and [`ReflectDeserializer`], implementors should be sure to register the33/// [`ReflectDeserializeWithRegistry`] type data.34/// This can be done [via the registry] or by adding `#[reflect(DeserializeWithRegistry)]` to35/// the type definition.36///37/// [`Deserialize`]: ::serde::Deserialize38/// [`SerializeWithRegistry`]: crate::serde::SerializeWithRegistry39/// [type data]: ReflectDeserializeWithRegistry40/// [`TypedReflectDeserializer`]: crate::serde::TypedReflectDeserializer41/// [`ReflectDeserializer`]: crate::serde::ReflectDeserializer42/// [via the registry]: TypeRegistry::register_type_data43pub trait DeserializeWithRegistry<'de>: Sized {44/// Deserialize this value using the given [Deserializer] and [`TypeRegistry`].45///46/// [`Deserializer`]: ::serde::Deserializer47fn deserialize<D>(deserializer: D, registry: &TypeRegistry) -> Result<Self, D::Error>48where49D: Deserializer<'de>;50}5152/// Type data used to deserialize a [`PartialReflect`] type with a custom [`DeserializeWithRegistry`] implementation.53#[derive(Clone)]54pub struct ReflectDeserializeWithRegistry {55deserialize: fn(56deserializer: &mut dyn erased_serde::Deserializer,57registry: &TypeRegistry,58) -> Result<Box<dyn PartialReflect>, erased_serde::Error>,59}6061impl ReflectDeserializeWithRegistry {62/// Deserialize a [`PartialReflect`] type with this type data's custom [`DeserializeWithRegistry`] implementation.63pub fn deserialize<'de, D>(64&self,65deserializer: D,66registry: &TypeRegistry,67) -> Result<Box<dyn PartialReflect>, D::Error>68where69D: Deserializer<'de>,70{71let mut erased = <dyn erased_serde::Deserializer>::erase(deserializer);72(self.deserialize)(&mut erased, registry).map_err(make_custom_error)73}74}7576impl<T: PartialReflect + for<'de> DeserializeWithRegistry<'de>> FromType<T>77for ReflectDeserializeWithRegistry78{79fn from_type() -> Self {80Self {81deserialize: |deserializer, registry| {82Ok(Box::new(T::deserialize(deserializer, registry)?))83},84}85}86}878889