bevy_reflect/serde/ser/
enums.rs1use crate::{
2 serde::{ser::error_utils::make_custom_error, TypedReflectSerializer},
3 Enum, TypeInfo, TypeRegistry, VariantInfo, VariantType,
4};
5use serde::{
6 ser::{SerializeStructVariant, SerializeTupleVariant},
7 Serialize,
8};
9
10use super::ReflectSerializerProcessor;
11
12pub(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
19impl<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}