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