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