Skip to content

Commit 0981e38

Browse files
committed
fix docs for deserialize processor
1 parent 1b0d2f7 commit 0981e38

File tree

1 file changed

+109
-46
lines changed

1 file changed

+109
-46
lines changed

crates/bevy_reflect/src/serde/de/deserializer.rs

Lines changed: 109 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,10 @@ use serde::de::{DeserializeSeed, Error, IgnoredAny, MapAccess, Visitor};
2525
/// pass it in to your deserializer.
2626
///
2727
/// Whenever the deserializer attempts to deserialize a value, it will first
28-
/// check using [`should_deserialize`] whether this processor should take
29-
/// control of the deserialization. If so, the processor returns a
30-
/// [`Box<dyn FnOnce>`] which then uses the [`erased_serde::Deserializer`] to
31-
/// give back either a [`Box<dyn PartialReflect>`] or an error.
32-
///
33-
/// Because the processor returns a [`Box<dyn FnOnce>`], you can change the
34-
/// behaviour of the deserializer based on the [`TypeRegistration`].
28+
/// call [`try_deserialize`] on your processor, which may take ownership of the
29+
/// deserializer and give back a [`Box<dyn PartialReflect>`], or return
30+
/// ownership of the deserializer back to the deserializer, and continue with
31+
/// the default logic.
3532
///
3633
/// # Examples
3734
///
@@ -74,45 +71,111 @@ use serde::de::{DeserializeSeed, Error, IgnoredAny, MapAccess, Visitor};
7471
/// }
7572
///
7673
/// # type AssetError = Box<dyn core::error::Error>;
77-
/// # fn load<AssetPathVisitor: for<'de> Visitor<'de, Value = ()> + Copy>(
78-
/// # asset_bytes: &[u8],
79-
/// # type_registry: &TypeRegistry,
80-
/// # load_context: &mut LoadContext,
81-
/// # AssetPathVisitor: AssetPathVisitor,
82-
/// # ) -> Result<MyAsset, AssetError> {
83-
/// let mut ron_deserializer = ron::Deserializer::from_bytes(asset_bytes)?;
84-
/// let mut processor = ReflectDeserializerProcessor::new(|registration: &TypeRegistration| {
85-
/// let Some(reflect_handle) = registration.data::<ReflectHandle>() else {
86-
/// return None;
87-
/// };
88-
///
89-
/// Some(Box::new(|deserializer| {
90-
/// let asset_type_id = reflect_handle.asset_type_id();
91-
///
92-
/// let asset_path = deserializer.deserialize_str(AssetPathVisitor)?;
93-
///
94-
/// // takes in `load_context` from its scope
95-
/// let handle: Handle<LoadedUntypedAsset> = load_context
96-
/// .load()
97-
/// .with_asset_type_id(asset_type_id)
98-
/// .untyped()
99-
/// .load_asset(asset_path);
100-
/// # let _: Result<_, ()> = {
101-
/// Ok(Box::new(handle))
102-
/// # };
103-
/// # unimplemented!()
104-
/// }))
105-
/// });
106-
/// let reflect_deserializer =
107-
/// ReflectDeserializer::new_with_processor(type_registry, &mut processor);
108-
/// let asset = reflect_deserializer.deserialize(&mut ron_deserializer)?;
109-
/// # unimplemented!()
74+
/// fn load(
75+
/// asset_bytes: &[u8],
76+
/// type_registry: &TypeRegistry,
77+
/// load_context: &mut LoadContext
78+
/// ) -> Result<MyAsset, AssetError> {
79+
/// # unimplemented!()
11080
/// # }
81+
/// # fn _load<AssetPathVisitor: for<'de> Visitor<'de, Value = ()> + Copy>(
82+
/// # asset_bytes: &[u8],
83+
/// # type_registry: &TypeRegistry,
84+
/// # load_context: &mut LoadContext,
85+
/// # AssetPathVisitor: AssetPathVisitor,
86+
/// # ) -> Result<MyAsset, AssetError> {
87+
/// struct HandleProcessor<'a> {
88+
/// load_context: &'a mut LoadContext,
89+
/// }
90+
///
91+
/// impl ReflectDeserializerProcessor for HandleProcessor<'_> {
92+
/// fn try_deserialize<'de, D>(
93+
/// &mut self,
94+
/// registration: &TypeRegistration,
95+
/// deserializer: D,
96+
/// ) -> Result<Result<Box<dyn PartialReflect>, D>, D::Error>
97+
/// where
98+
/// D: serde::Deserializer<'de>
99+
/// {
100+
/// let Some(reflect_handle) = registration.data::<ReflectHandle>() else {
101+
/// return None;
102+
/// };
103+
///
104+
///
105+
/// let asset_type_id = reflect_handle.asset_type_id();
106+
///
107+
/// let asset_path = deserializer.deserialize_str(AssetPathVisitor)?;
108+
///
109+
/// // takes in `load_context` from its scope
110+
/// let handle: Handle<LoadedUntypedAsset> = load_context
111+
/// .load()
112+
/// .with_asset_type_id(asset_type_id)
113+
/// .untyped()
114+
/// .load_asset(asset_path);
115+
/// # let _: Result<_, ()> = {
116+
/// Ok(Box::new(handle))
117+
/// # };
118+
/// # unimplemented!()
119+
/// }
120+
/// }
121+
///
122+
/// let mut ron_deserializer = ron::Deserializer::from_bytes(asset_bytes)?;
123+
/// let mut processor = HandleProcessor { load_context };
124+
/// let reflect_deserializer =
125+
/// ReflectDeserializer::with_processor(type_registry, &mut processor);
126+
/// let asset = reflect_deserializer.deserialize(&mut ron_deserializer)?;
127+
/// # unimplemented!()
128+
/// }
111129
/// ```
112130
///
113-
/// [`should_deserialize`]: Self::should_deserialize
114-
/// [`deserialize`]: Self::deserialize
131+
/// [`try_deserialize`]: Self::try_deserialize
115132
pub trait ReflectDeserializerProcessor {
133+
/// Attempts to deserialize the value which a [`TypedReflectDeserializer`]
134+
/// is currently looking at, and knows the type of.
135+
///
136+
/// If you've read the `registration` and want to override the default
137+
/// deserialization, return `Ok(Ok(value))` with the boxed reflected value
138+
/// that you want to assign this value to. The type inside the box must
139+
/// be the same one as the `registration` is for.
140+
///
141+
/// If you don't want to override the deserialization, return ownership of
142+
/// the deserializer back via `Ok(Err(deserializer))`.
143+
///
144+
/// Note that, if you do want to return a value, you *must* read from the
145+
/// deserializer passed to this function (you are free to ignore the result
146+
/// though). Otherwise, the deserializer will be in an inconsistent state,
147+
/// and future value parsing will fail.
148+
///
149+
/// # Examples
150+
///
151+
/// Correct way to return a constant value (not using any output from the
152+
/// deserializer):
153+
///
154+
/// ```
155+
/// # use bevy_reflect::prelude::*;
156+
/// # use bevy_reflect::serde::de::ReflectDeserializerProcessor};
157+
/// use serde::de::IgnoredAny;
158+
///
159+
/// struct ConstantI32Processor;
160+
///
161+
/// impl ReflectDeserializerProcessor for ConstantI32Processor {
162+
/// fn try_deserialize<'de, D>(
163+
/// &mut self,
164+
/// registration: &TypeRegistration,
165+
/// deserializer: D,
166+
/// ) -> Result<Result<Box<dyn PartialReflect>, D>, D::Error>
167+
/// where
168+
/// D: serde::Deserializer<'de>
169+
/// {
170+
/// if registration.type_id() == TypeId::of::<i32>() {
171+
/// _ = deserializer.deserialize_ignored_any(IgnoredAny);
172+
/// Ok(Ok(Box::new(42_i32)))
173+
/// } else {
174+
/// Ok(Err(deserializer))
175+
/// }
176+
/// }
177+
/// }
178+
/// ```
116179
fn try_deserialize<'de, D>(
117180
&mut self,
118181
registration: &TypeRegistration,
@@ -164,7 +227,7 @@ impl ReflectDeserializerProcessor for () {
164227
///
165228
/// If you want to override deserialization for a specific [`TypeRegistration`],
166229
/// you can pass in a reference to a [`ReflectDeserializerProcessor`] which will
167-
/// take priority over all other deserialization methods - see [`new_with_processor`].
230+
/// take priority over all other deserialization methods - see [`with_processor`].
168231
///
169232
/// # Example
170233
///
@@ -218,7 +281,7 @@ impl ReflectDeserializerProcessor for () {
218281
/// [`Box<DynamicList>`]: crate::DynamicList
219282
/// [`FromReflect`]: crate::FromReflect
220283
/// [`ReflectFromReflect`]: crate::ReflectFromReflect
221-
/// [`new_with_processor`]: Self::new_with_processor
284+
/// [`with_processor`]: Self::with_processor
222285
pub struct ReflectDeserializer<'a, P> {
223286
registry: &'a TypeRegistry,
224287
processor: Option<&'a mut P>,
@@ -332,7 +395,7 @@ impl<'de, P: ReflectDeserializerProcessor> DeserializeSeed<'de> for ReflectDeser
332395
///
333396
/// If you want to override deserialization for a specific [`TypeRegistration`],
334397
/// you can pass in a reference to a [`ReflectDeserializerProcessor`] which will
335-
/// take priority over all other deserialization methods - see [`new_with_processor`].
398+
/// take priority over all other deserialization methods - see [`with_processor`].
336399
///
337400
/// # Example
338401
///
@@ -385,7 +448,7 @@ impl<'de, P: ReflectDeserializerProcessor> DeserializeSeed<'de> for ReflectDeser
385448
/// [`Box<DynamicList>`]: crate::DynamicList
386449
/// [`FromReflect`]: crate::FromReflect
387450
/// [`ReflectFromReflect`]: crate::ReflectFromReflect
388-
/// [`new_with_processor`]: Self::new_with_processor
451+
/// [`with_processor`]: Self::with_processor
389452
pub struct TypedReflectDeserializer<'a, P> {
390453
registration: &'a TypeRegistration,
391454
registry: &'a TypeRegistry,

0 commit comments

Comments
 (0)