bevy_reflect/serde/de/processor.rs
1use crate::{PartialReflect, TypeRegistration, TypeRegistry};
2use alloc::boxed::Box;
3
4/// Allows overriding the default deserialization behavior of
5/// [`ReflectDeserializer`] and [`TypedReflectDeserializer`] for specific
6/// [`TypeRegistration`]s.
7///
8/// When deserializing a reflected value, you may want to override the default
9/// behavior and use your own logic for deserialization. This logic may also
10/// be context-dependent, and only apply for a single use of your
11/// [`ReflectDeserializer`]. To achieve this, you can create a processor and
12/// pass it in to your deserializer.
13///
14/// Whenever the deserializer attempts to deserialize a value, it will first
15/// call [`try_deserialize`] on your processor, which may take ownership of the
16/// deserializer and give back a [`Box<dyn PartialReflect>`], or return
17/// ownership of the deserializer back, and continue with the default logic.
18///
19/// The serialization equivalent of this is [`ReflectSerializerProcessor`].
20///
21/// # Compared to [`DeserializeWithRegistry`]
22///
23/// [`DeserializeWithRegistry`] allows you to define how your type will be
24/// deserialized by a [`TypedReflectDeserializer`], given the extra context of
25/// the [`TypeRegistry`]. If your type can be deserialized entirely from that,
26/// then you should prefer implementing that trait instead of using a processor.
27///
28/// However, you may need more context-dependent data which is only present in
29/// the scope where you create the [`TypedReflectDeserializer`]. For example, in
30/// an asset loader, the `&mut LoadContext` you get is only valid from within
31/// the `load` function. This is where a processor is useful, as the processor
32/// can capture local variables.
33///
34/// A [`ReflectDeserializerProcessor`] always takes priority over a
35/// [`DeserializeWithRegistry`] implementation, so this is also useful for
36/// overriding deserialization behavior if you need to do something custom.
37///
38/// # Examples
39///
40/// Deserializing a reflected value in an asset loader, and replacing asset
41/// handles with a loaded equivalent:
42///
43/// ```
44/// # use bevy_reflect::serde::{ReflectDeserializer, ReflectDeserializerProcessor};
45/// # use bevy_reflect::{PartialReflect, Reflect, TypeData, TypeRegistration, TypeRegistry};
46/// # use serde::de::{DeserializeSeed, Deserializer, Visitor};
47/// # use std::marker::PhantomData;
48/// #
49/// # #[derive(Debug, Clone, Reflect)]
50/// # struct LoadedUntypedAsset;
51/// # #[derive(Debug, Clone, Reflect)]
52/// # struct Handle<T: Reflect>(T);
53/// # #[derive(Debug, Clone, Reflect)]
54/// # struct Mesh;
55/// #
56/// # struct LoadContext;
57/// # impl LoadContext {
58/// # fn load(&mut self) -> &mut Self { unimplemented!() }
59/// # fn with_asset_type_id(&mut self, (): ()) -> &mut Self { unimplemented!() }
60/// # fn untyped(&mut self) -> &mut Self { unimplemented!() }
61/// # fn load_asset(&mut self, (): ()) -> Handle<LoadedUntypedAsset> { unimplemented!() }
62/// # }
63/// #
64/// # struct ReflectHandle;
65/// # impl TypeData for ReflectHandle {
66/// # fn clone_type_data(&self) -> Box<dyn TypeData> {
67/// # unimplemented!()
68/// # }
69/// # }
70/// # impl ReflectHandle {
71/// # fn asset_type_id(&self) {
72/// # unimplemented!()
73/// # }
74/// # }
75/// #
76/// # struct AssetPathVisitor;
77/// # impl<'de> Visitor<'de> for AssetPathVisitor {
78/// # type Value = ();
79/// # fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { unimplemented!() }
80/// # }
81/// # type AssetError = Box<dyn core::error::Error>;
82/// #[derive(Debug, Clone, Reflect)]
83/// struct MyAsset {
84/// name: String,
85/// mesh: Handle<Mesh>,
86/// }
87///
88/// fn load(
89/// asset_bytes: &[u8],
90/// type_registry: &TypeRegistry,
91/// load_context: &mut LoadContext,
92/// ) -> Result<MyAsset, AssetError> {
93/// struct HandleProcessor<'a> {
94/// load_context: &'a mut LoadContext,
95/// }
96///
97/// impl ReflectDeserializerProcessor for HandleProcessor<'_> {
98/// fn try_deserialize<'de, D>(
99/// &mut self,
100/// registration: &TypeRegistration,
101/// _registry: &TypeRegistry,
102/// deserializer: D,
103/// ) -> Result<Result<Box<dyn PartialReflect>, D>, D::Error>
104/// where
105/// D: Deserializer<'de>,
106/// {
107/// let Some(reflect_handle) = registration.data::<ReflectHandle>() else {
108/// // we don't want to deserialize this - give the deserializer back
109/// return Ok(Err(deserializer));
110/// };
111///
112/// let asset_type_id = reflect_handle.asset_type_id();
113/// let asset_path = deserializer.deserialize_str(AssetPathVisitor)?;
114///
115/// let handle: Handle<LoadedUntypedAsset> = self.load_context
116/// .load()
117/// .with_asset_type_id(asset_type_id)
118/// .untyped()
119/// .load_asset(asset_path);
120/// # let _: Result<_, ()> = {
121/// Ok(Box::new(handle))
122/// # };
123/// # unimplemented!()
124/// }
125/// }
126///
127/// let mut ron_deserializer = ron::Deserializer::from_bytes(asset_bytes)?;
128/// let mut processor = HandleProcessor { load_context };
129/// let reflect_deserializer =
130/// ReflectDeserializer::with_processor(type_registry, &mut processor);
131/// let asset = reflect_deserializer.deserialize(&mut ron_deserializer)?;
132/// # unimplemented!()
133/// }
134/// ```
135///
136/// [`ReflectDeserializer`]: crate::serde::ReflectDeserializer
137/// [`TypedReflectDeserializer`]: crate::serde::TypedReflectDeserializer
138/// [`try_deserialize`]: Self::try_deserialize
139/// [`DeserializeWithRegistry`]: crate::serde::DeserializeWithRegistry
140/// [`ReflectSerializerProcessor`]: crate::serde::ReflectSerializerProcessor
141pub trait ReflectDeserializerProcessor {
142 /// Attempts to deserialize the value which a [`TypedReflectDeserializer`]
143 /// is currently looking at, and knows the type of.
144 ///
145 /// If you've read the `registration` and want to override the default
146 /// deserialization, return `Ok(Ok(value))` with the boxed reflected value
147 /// that you want to assign this value to. The type inside the box must
148 /// be the same one as the `registration` is for, otherwise future
149 /// reflection operations (such as using [`FromReflect`] to convert the
150 /// resulting [`Box<dyn PartialReflect>`] into a concrete type) will fail.
151 ///
152 /// If you don't want to override the deserialization, return ownership of
153 /// the deserializer back via `Ok(Err(deserializer))`.
154 ///
155 /// Note that, if you do want to return a value, you *must* read from the
156 /// deserializer passed to this function (you are free to ignore the result
157 /// though). Otherwise, the deserializer will be in an inconsistent state,
158 /// and future value parsing will fail.
159 ///
160 /// # Examples
161 ///
162 /// Correct way to return a constant value (not using any output from the
163 /// deserializer):
164 ///
165 /// ```
166 /// # use bevy_reflect::{TypeRegistration, PartialReflect, TypeRegistry};
167 /// # use bevy_reflect::serde::ReflectDeserializerProcessor;
168 /// # use core::any::TypeId;
169 /// use serde::de::IgnoredAny;
170 ///
171 /// struct ConstantI32Processor;
172 ///
173 /// impl ReflectDeserializerProcessor for ConstantI32Processor {
174 /// fn try_deserialize<'de, D>(
175 /// &mut self,
176 /// registration: &TypeRegistration,
177 /// _registry: &TypeRegistry,
178 /// deserializer: D,
179 /// ) -> Result<Result<Box<dyn PartialReflect>, D>, D::Error>
180 /// where
181 /// D: serde::Deserializer<'de>
182 /// {
183 /// if registration.type_id() == TypeId::of::<i32>() {
184 /// _ = deserializer.deserialize_ignored_any(IgnoredAny);
185 /// Ok(Ok(Box::new(42_i32)))
186 /// } else {
187 /// Ok(Err(deserializer))
188 /// }
189 /// }
190 /// }
191 /// ```
192 ///
193 /// [`TypedReflectDeserializer`]: crate::serde::TypedReflectDeserializer
194 /// [`FromReflect`]: crate::FromReflect
195 fn try_deserialize<'de, D>(
196 &mut self,
197 registration: &TypeRegistration,
198 registry: &TypeRegistry,
199 deserializer: D,
200 ) -> Result<Result<Box<dyn PartialReflect>, D>, D::Error>
201 where
202 D: serde::Deserializer<'de>;
203}
204
205impl ReflectDeserializerProcessor for () {
206 fn try_deserialize<'de, D>(
207 &mut self,
208 _registration: &TypeRegistration,
209 _registry: &TypeRegistry,
210 deserializer: D,
211 ) -> Result<Result<Box<dyn PartialReflect>, D>, D::Error>
212 where
213 D: serde::Deserializer<'de>,
214 {
215 Ok(Err(deserializer))
216 }
217}