bevy_reflect/serde/ser/
custom_serialization.rs

1use crate::serde::ser::error_utils::make_custom_error;
2#[cfg(feature = "debug_stack")]
3use crate::serde::ser::error_utils::TYPE_INFO_STACK;
4use crate::serde::ReflectSerializeWithRegistry;
5use crate::{PartialReflect, ReflectSerialize, TypeRegistry};
6use core::borrow::Borrow;
7use serde::{Serialize, Serializer};
8
9/// Attempts to serialize a [`PartialReflect`] value with custom [`ReflectSerialize`]
10/// or [`ReflectSerializeWithRegistry`] type data.
11///
12/// On success, returns the result of the serialization.
13/// On failure, returns the original serializer and the error that occurred.
14pub(super) fn try_custom_serialize<S: Serializer>(
15    value: &dyn PartialReflect,
16    type_registry: &TypeRegistry,
17    serializer: S,
18) -> Result<Result<S::Ok, S::Error>, (S, S::Error)> {
19    let Some(value) = value.try_as_reflect() else {
20        return Err((
21            serializer,
22            make_custom_error(format_args!(
23                "type `{}` does not implement `Reflect`",
24                value.reflect_type_path()
25            )),
26        ));
27    };
28
29    let info = value.reflect_type_info();
30
31    let Some(registration) = type_registry.get(info.type_id()) else {
32        return Err((
33            serializer,
34            make_custom_error(format_args!(
35                "type `{}` is not registered in the type registry",
36                info.type_path(),
37            )),
38        ));
39    };
40
41    if let Some(reflect_serialize) = registration.data::<ReflectSerialize>() {
42        #[cfg(feature = "debug_stack")]
43        TYPE_INFO_STACK.with_borrow_mut(crate::type_info_stack::TypeInfoStack::pop);
44
45        Ok(reflect_serialize
46            .get_serializable(value)
47            .borrow()
48            .serialize(serializer))
49    } else if let Some(reflect_serialize_with_registry) =
50        registration.data::<ReflectSerializeWithRegistry>()
51    {
52        #[cfg(feature = "debug_stack")]
53        TYPE_INFO_STACK.with_borrow_mut(crate::type_info_stack::TypeInfoStack::pop);
54
55        Ok(reflect_serialize_with_registry.serialize(value, serializer, type_registry))
56    } else {
57        Err((serializer, make_custom_error(format_args!(
58            "type `{}` did not register the `ReflectSerialize` or `ReflectSerializeWithRegistry` type data. For certain types, this may need to be registered manually using `register_type_data`",
59            info.type_path(),
60        ))))
61    }
62}