|  | 
|  | 1 | +use crate::serde::de::error_utils::make_custom_error; | 
|  | 2 | +use crate::{FromType, PartialReflect, TypeRegistry}; | 
|  | 3 | +use serde::Deserializer; | 
|  | 4 | + | 
|  | 5 | +/// Trait used to provide finer control when deserializing a reflected type with one of | 
|  | 6 | +/// 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 information | 
|  | 11 | +/// to deserialize our type. | 
|  | 12 | +/// | 
|  | 13 | +/// This can be useful when writing a custom reflection deserializer where we may | 
|  | 14 | +/// want to handle parts of the deserialization process, but temporarily pass control | 
|  | 15 | +/// to the standard reflection deserializer for other parts. | 
|  | 16 | +/// | 
|  | 17 | +/// For the serialization equivalent of this trait, see [`SerializeWithRegistry`]. | 
|  | 18 | +/// | 
|  | 19 | +/// # Rationale | 
|  | 20 | +/// | 
|  | 21 | +/// Without this trait and its associated [type data], such a deserializer would have to | 
|  | 22 | +/// write out all of the deserialization logic itself, possibly including | 
|  | 23 | +/// unnecessary code duplication and trivial implementations. | 
|  | 24 | +/// | 
|  | 25 | +/// This is because a normal [`Deserialize`] implementation has no knowledge of the | 
|  | 26 | +/// [`TypeRegistry`] and therefore cannot create a reflection-based deserializer for | 
|  | 27 | +/// nested items. | 
|  | 28 | +/// | 
|  | 29 | +/// # Implementors | 
|  | 30 | +/// | 
|  | 31 | +/// In order for this to work with the reflection deserializers like [`TypedReflectDeserializer`] | 
|  | 32 | +/// and [`ReflectDeserializer`], implementors should be sure to register the | 
|  | 33 | +/// [`ReflectDeserializeWithRegistry`] type data. | 
|  | 34 | +/// This can be done [via the registry] or by adding `#[reflect(DeserializeWithRegistry)]` to | 
|  | 35 | +/// the type definition. | 
|  | 36 | +/// | 
|  | 37 | +/// [`Deserialize`]: ::serde::Deserialize | 
|  | 38 | +/// [`SerializeWithRegistry`]: crate::serde::SerializeWithRegistry | 
|  | 39 | +/// [type data]: ReflectDeserializeWithRegistry | 
|  | 40 | +/// [`TypedReflectDeserializer`]: crate::serde::TypedReflectDeserializer | 
|  | 41 | +/// [`ReflectDeserializer`]: crate::serde::ReflectDeserializer | 
|  | 42 | +/// [via the registry]: TypeRegistry::register_type_data | 
|  | 43 | +pub trait DeserializeWithRegistry<'de>: PartialReflect + Sized { | 
|  | 44 | +    fn deserialize<D>(deserializer: D, registry: &TypeRegistry) -> Result<Self, D::Error> | 
|  | 45 | +    where | 
|  | 46 | +        D: Deserializer<'de>; | 
|  | 47 | +} | 
|  | 48 | + | 
|  | 49 | +/// Type data used to deserialize a [`PartialReflect`] type with a custom [`DeserializeWithRegistry`] implementation. | 
|  | 50 | +#[derive(Clone)] | 
|  | 51 | +pub struct ReflectDeserializeWithRegistry { | 
|  | 52 | +    deserialize: fn( | 
|  | 53 | +        deserializer: &mut dyn erased_serde::Deserializer, | 
|  | 54 | +        registry: &TypeRegistry, | 
|  | 55 | +    ) -> Result<Box<dyn PartialReflect>, erased_serde::Error>, | 
|  | 56 | +} | 
|  | 57 | + | 
|  | 58 | +impl ReflectDeserializeWithRegistry { | 
|  | 59 | +    /// Deserialize a [`PartialReflect`] type with this type data's custom [`DeserializeWithRegistry`] implementation. | 
|  | 60 | +    pub fn deserialize<'de, D>( | 
|  | 61 | +        &self, | 
|  | 62 | +        deserializer: D, | 
|  | 63 | +        registry: &TypeRegistry, | 
|  | 64 | +    ) -> Result<Box<dyn PartialReflect>, D::Error> | 
|  | 65 | +    where | 
|  | 66 | +        D: Deserializer<'de>, | 
|  | 67 | +    { | 
|  | 68 | +        let mut erased = <dyn erased_serde::Deserializer>::erase(deserializer); | 
|  | 69 | +        (self.deserialize)(&mut erased, registry).map_err(make_custom_error) | 
|  | 70 | +    } | 
|  | 71 | +} | 
|  | 72 | + | 
|  | 73 | +impl<T: PartialReflect + for<'de> DeserializeWithRegistry<'de>> FromType<T> | 
|  | 74 | +    for ReflectDeserializeWithRegistry | 
|  | 75 | +{ | 
|  | 76 | +    fn from_type() -> Self { | 
|  | 77 | +        Self { | 
|  | 78 | +            deserialize: |deserializer, registry| { | 
|  | 79 | +                Ok(Box::new(T::deserialize(deserializer, registry)?)) | 
|  | 80 | +            }, | 
|  | 81 | +        } | 
|  | 82 | +    } | 
|  | 83 | +} | 
0 commit comments