bevy_reflect/serde/ser/
custom_serialization.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
use crate::serde::ser::error_utils::make_custom_error;
#[cfg(feature = "debug_stack")]
use crate::serde::ser::error_utils::TYPE_INFO_STACK;
use crate::serde::ReflectSerializeWithRegistry;
use crate::{PartialReflect, ReflectSerialize, TypeRegistry};
use core::borrow::Borrow;
use serde::{Serialize, Serializer};

/// Attempts to serialize a [`PartialReflect`] value with custom [`ReflectSerialize`]
/// or [`ReflectSerializeWithRegistry`] type data.
///
/// On success, returns the result of the serialization.
/// On failure, returns the original serializer and the error that occurred.
pub(super) fn try_custom_serialize<S: Serializer>(
    value: &dyn PartialReflect,
    type_registry: &TypeRegistry,
    serializer: S,
) -> Result<Result<S::Ok, S::Error>, (S, S::Error)> {
    let Some(value) = value.try_as_reflect() else {
        return Err((
            serializer,
            make_custom_error(format_args!(
                "type `{}` does not implement `Reflect`",
                value.reflect_type_path()
            )),
        ));
    };

    let info = value.reflect_type_info();

    let Some(registration) = type_registry.get(info.type_id()) else {
        return Err((
            serializer,
            make_custom_error(format_args!(
                "type `{}` is not registered in the type registry",
                info.type_path(),
            )),
        ));
    };

    if let Some(reflect_serialize) = registration.data::<ReflectSerialize>() {
        #[cfg(feature = "debug_stack")]
        TYPE_INFO_STACK.with_borrow_mut(crate::type_info_stack::TypeInfoStack::pop);

        Ok(reflect_serialize
            .get_serializable(value)
            .borrow()
            .serialize(serializer))
    } else if let Some(reflect_serialize_with_registry) =
        registration.data::<ReflectSerializeWithRegistry>()
    {
        #[cfg(feature = "debug_stack")]
        TYPE_INFO_STACK.with_borrow_mut(crate::type_info_stack::TypeInfoStack::pop);

        Ok(reflect_serialize_with_registry.serialize(value, serializer, type_registry))
    } else {
        Err((serializer, make_custom_error(format_args!(
            "type `{}` did not register the `ReflectSerialize` or `ReflectSerializeWithRegistry` type data. For certain types, this may need to be registered manually using `register_type_data`",
            info.type_path(),
        ))))
    }
}