Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_reflect/src/serde/ser/enums.rs
6600 views
1
use crate::{
2
serde::{ser::error_utils::make_custom_error, TypedReflectSerializer},
3
Enum, TypeInfo, TypeRegistry, VariantInfo, VariantType,
4
};
5
use serde::{
6
ser::{SerializeStructVariant, SerializeTupleVariant},
7
Serialize,
8
};
9
10
use super::ReflectSerializerProcessor;
11
12
/// A serializer for [`Enum`] values.
13
pub(super) struct EnumSerializer<'a, P> {
14
pub enum_value: &'a dyn Enum,
15
pub registry: &'a TypeRegistry,
16
pub processor: Option<&'a P>,
17
}
18
19
impl<P: ReflectSerializerProcessor> Serialize for EnumSerializer<'_, P> {
20
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
21
where
22
S: serde::Serializer,
23
{
24
let type_info = self.enum_value.get_represented_type_info().ok_or_else(|| {
25
make_custom_error(format_args!(
26
"cannot get type info for `{}`",
27
self.enum_value.reflect_type_path()
28
))
29
})?;
30
31
let enum_info = match type_info {
32
TypeInfo::Enum(enum_info) => enum_info,
33
info => {
34
return Err(make_custom_error(format_args!(
35
"expected enum type but received {info:?}"
36
)));
37
}
38
};
39
40
let enum_name = enum_info.type_path_table().ident().unwrap();
41
let variant_index = self.enum_value.variant_index() as u32;
42
let variant_info = enum_info
43
.variant_at(variant_index as usize)
44
.ok_or_else(|| {
45
make_custom_error(format_args!(
46
"variant at index `{variant_index}` does not exist",
47
))
48
})?;
49
let variant_name = variant_info.name();
50
let variant_type = self.enum_value.variant_type();
51
let field_len = self.enum_value.field_len();
52
53
match variant_type {
54
VariantType::Unit => {
55
if type_info.type_path_table().module_path() == Some("core::option")
56
&& type_info.type_path_table().ident() == Some("Option")
57
{
58
serializer.serialize_none()
59
} else {
60
serializer.serialize_unit_variant(enum_name, variant_index, variant_name)
61
}
62
}
63
VariantType::Struct => {
64
let struct_info = match variant_info {
65
VariantInfo::Struct(struct_info) => struct_info,
66
info => {
67
return Err(make_custom_error(format_args!(
68
"expected struct variant type but received {info:?}",
69
)));
70
}
71
};
72
73
let mut state = serializer.serialize_struct_variant(
74
enum_name,
75
variant_index,
76
variant_name,
77
field_len,
78
)?;
79
for (index, field) in self.enum_value.iter_fields().enumerate() {
80
let field_info = struct_info.field_at(index).unwrap();
81
state.serialize_field(
82
field_info.name(),
83
&TypedReflectSerializer::new_internal(
84
field.value(),
85
self.registry,
86
self.processor,
87
),
88
)?;
89
}
90
state.end()
91
}
92
VariantType::Tuple if field_len == 1 => {
93
let field = self.enum_value.field_at(0).unwrap();
94
95
if type_info.type_path_table().module_path() == Some("core::option")
96
&& type_info.type_path_table().ident() == Some("Option")
97
{
98
serializer.serialize_some(&TypedReflectSerializer::new_internal(
99
field,
100
self.registry,
101
self.processor,
102
))
103
} else {
104
serializer.serialize_newtype_variant(
105
enum_name,
106
variant_index,
107
variant_name,
108
&TypedReflectSerializer::new_internal(field, self.registry, self.processor),
109
)
110
}
111
}
112
VariantType::Tuple => {
113
let mut state = serializer.serialize_tuple_variant(
114
enum_name,
115
variant_index,
116
variant_name,
117
field_len,
118
)?;
119
for field in self.enum_value.iter_fields() {
120
state.serialize_field(&TypedReflectSerializer::new_internal(
121
field.value(),
122
self.registry,
123
self.processor,
124
))?;
125
}
126
state.end()
127
}
128
}
129
}
130
}
131
132