Path: blob/main/crates/bevy_reflect/src/serde/de/enums.rs
6600 views
use crate::{1serde::{2de::{3error_utils::make_custom_error,4helpers::ExpectedValues,5registration_utils::try_get_registration,6struct_utils::{visit_struct, visit_struct_seq},7tuple_utils::{visit_tuple, TupleLikeInfo},8},9TypedReflectDeserializer,10},11DynamicEnum, DynamicStruct, DynamicTuple, DynamicVariant, EnumInfo, StructVariantInfo,12TupleVariantInfo, TypeRegistration, TypeRegistry, VariantInfo,13};14use core::{fmt, fmt::Formatter};15use serde::de::{DeserializeSeed, EnumAccess, Error, MapAccess, SeqAccess, VariantAccess, Visitor};1617use super::ReflectDeserializerProcessor;1819/// A [`Visitor`] for deserializing [`Enum`] values.20///21/// [`Enum`]: crate::Enum22pub(super) struct EnumVisitor<'a, P> {23pub enum_info: &'static EnumInfo,24pub registration: &'a TypeRegistration,25pub registry: &'a TypeRegistry,26pub processor: Option<&'a mut P>,27}2829impl<'de, P: ReflectDeserializerProcessor> Visitor<'de> for EnumVisitor<'_, P> {30type Value = DynamicEnum;3132fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {33formatter.write_str("reflected enum value")34}3536fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>37where38A: EnumAccess<'de>,39{40let mut dynamic_enum = DynamicEnum::default();41let (variant_info, variant) = data.variant_seed(VariantDeserializer {42enum_info: self.enum_info,43})?;4445let value: DynamicVariant = match variant_info {46VariantInfo::Unit(..) => variant.unit_variant()?.into(),47VariantInfo::Struct(struct_info) => variant48.struct_variant(49struct_info.field_names(),50StructVariantVisitor {51struct_info,52registration: self.registration,53registry: self.registry,54processor: self.processor,55},56)?57.into(),58VariantInfo::Tuple(tuple_info) if tuple_info.field_len() == 1 => {59let registration = try_get_registration(60*TupleLikeInfo::field_at(tuple_info, 0)?.ty(),61self.registry,62)?;63let value =64variant.newtype_variant_seed(TypedReflectDeserializer::new_internal(65registration,66self.registry,67self.processor,68))?;69let mut dynamic_tuple = DynamicTuple::default();70dynamic_tuple.insert_boxed(value);71dynamic_tuple.into()72}73VariantInfo::Tuple(tuple_info) => variant74.tuple_variant(75tuple_info.field_len(),76TupleVariantVisitor {77tuple_info,78registration: self.registration,79registry: self.registry,80processor: self.processor,81},82)?83.into(),84};85let variant_name = variant_info.name();86let variant_index = self87.enum_info88.index_of(variant_name)89.expect("variant should exist");90dynamic_enum.set_variant_with_index(variant_index, variant_name, value);91Ok(dynamic_enum)92}93}9495struct VariantDeserializer {96enum_info: &'static EnumInfo,97}9899impl<'de> DeserializeSeed<'de> for VariantDeserializer {100type Value = &'static VariantInfo;101102fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>103where104D: serde::Deserializer<'de>,105{106struct VariantVisitor(&'static EnumInfo);107108impl<'de> Visitor<'de> for VariantVisitor {109type Value = &'static VariantInfo;110111fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {112formatter.write_str("expected either a variant index or variant name")113}114115fn visit_u32<E>(self, variant_index: u32) -> Result<Self::Value, E>116where117E: Error,118{119self.0.variant_at(variant_index as usize).ok_or_else(|| {120make_custom_error(format_args!(121"no variant found at index `{}` on enum `{}`",122variant_index,123self.0.type_path()124))125})126}127128fn visit_str<E>(self, variant_name: &str) -> Result<Self::Value, E>129where130E: Error,131{132self.0.variant(variant_name).ok_or_else(|| {133let names = self.0.iter().map(VariantInfo::name);134make_custom_error(format_args!(135"unknown variant `{}`, expected one of {:?}",136variant_name,137ExpectedValues::from_iter(names)138))139})140}141}142143deserializer.deserialize_identifier(VariantVisitor(self.enum_info))144}145}146147struct StructVariantVisitor<'a, P> {148struct_info: &'static StructVariantInfo,149registration: &'a TypeRegistration,150registry: &'a TypeRegistry,151processor: Option<&'a mut P>,152}153154impl<'de, P: ReflectDeserializerProcessor> Visitor<'de> for StructVariantVisitor<'_, P> {155type Value = DynamicStruct;156157fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {158formatter.write_str("reflected struct variant value")159}160161fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>162where163A: SeqAccess<'de>,164{165visit_struct_seq(166&mut seq,167self.struct_info,168self.registration,169self.registry,170self.processor,171)172}173174fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error>175where176V: MapAccess<'de>,177{178visit_struct(179&mut map,180self.struct_info,181self.registration,182self.registry,183self.processor,184)185}186}187188struct TupleVariantVisitor<'a, P> {189tuple_info: &'static TupleVariantInfo,190registration: &'a TypeRegistration,191registry: &'a TypeRegistry,192processor: Option<&'a mut P>,193}194195impl<'de, P: ReflectDeserializerProcessor> Visitor<'de> for TupleVariantVisitor<'_, P> {196type Value = DynamicTuple;197198fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {199formatter.write_str("reflected tuple variant value")200}201202fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>203where204V: SeqAccess<'de>,205{206visit_tuple(207&mut seq,208self.tuple_info,209self.registration,210self.registry,211self.processor,212)213}214}215216217