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}