bevy_reflect/serde/de/
deserialize_with_registry.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
use crate::serde::de::error_utils::make_custom_error;
use crate::{FromType, PartialReflect, TypeRegistry};
use serde::Deserializer;

/// Trait used to provide finer control when deserializing a reflected type with one of
/// the reflection deserializers.
///
/// This trait is the reflection equivalent of `serde`'s [`Deserialize`] trait.
/// The main difference is that this trait provides access to the [`TypeRegistry`],
/// which means that we can use the registry and all its stored type information
/// to deserialize our type.
///
/// This can be useful when writing a custom reflection deserializer where we may
/// want to handle parts of the deserialization process, but temporarily pass control
/// to the standard reflection deserializer for other parts.
///
/// For the serialization equivalent of this trait, see [`SerializeWithRegistry`].
///
/// # Rationale
///
/// Without this trait and its associated [type data], such a deserializer would have to
/// write out all of the deserialization logic itself, possibly including
/// unnecessary code duplication and trivial implementations.
///
/// This is because a normal [`Deserialize`] implementation has no knowledge of the
/// [`TypeRegistry`] and therefore cannot create a reflection-based deserializer for
/// nested items.
///
/// # Implementors
///
/// In order for this to work with the reflection deserializers like [`TypedReflectDeserializer`]
/// and [`ReflectDeserializer`], implementors should be sure to register the
/// [`ReflectDeserializeWithRegistry`] type data.
/// This can be done [via the registry] or by adding `#[reflect(DeserializeWithRegistry)]` to
/// the type definition.
///
/// [`Deserialize`]: ::serde::Deserialize
/// [`SerializeWithRegistry`]: crate::serde::SerializeWithRegistry
/// [type data]: ReflectDeserializeWithRegistry
/// [`TypedReflectDeserializer`]: crate::serde::TypedReflectDeserializer
/// [`ReflectDeserializer`]: crate::serde::ReflectDeserializer
/// [via the registry]: TypeRegistry::register_type_data
pub trait DeserializeWithRegistry<'de>: PartialReflect + Sized {
    fn deserialize<D>(deserializer: D, registry: &TypeRegistry) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>;
}

/// Type data used to deserialize a [`PartialReflect`] type with a custom [`DeserializeWithRegistry`] implementation.
#[derive(Clone)]
pub struct ReflectDeserializeWithRegistry {
    deserialize: fn(
        deserializer: &mut dyn erased_serde::Deserializer,
        registry: &TypeRegistry,
    ) -> Result<Box<dyn PartialReflect>, erased_serde::Error>,
}

impl ReflectDeserializeWithRegistry {
    /// Deserialize a [`PartialReflect`] type with this type data's custom [`DeserializeWithRegistry`] implementation.
    pub fn deserialize<'de, D>(
        &self,
        deserializer: D,
        registry: &TypeRegistry,
    ) -> Result<Box<dyn PartialReflect>, D::Error>
    where
        D: Deserializer<'de>,
    {
        let mut erased = <dyn erased_serde::Deserializer>::erase(deserializer);
        (self.deserialize)(&mut erased, registry).map_err(make_custom_error)
    }
}

impl<T: PartialReflect + for<'de> DeserializeWithRegistry<'de>> FromType<T>
    for ReflectDeserializeWithRegistry
{
    fn from_type() -> Self {
        Self {
            deserialize: |deserializer, registry| {
                Ok(Box::new(T::deserialize(deserializer, registry)?))
            },
        }
    }
}