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