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