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