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}