Path: blob/main/crates/bevy_reflect/src/serde/de/struct_utils.rs
9353 views
use crate::{1enums::StructVariantInfo,2serde::{3de::{4error_utils::make_custom_error,5helpers::{ExpectedValues, Ident},6registration_utils::try_get_registration,7},8SerializationData, TypedReflectDeserializer,9},10structs::{DynamicStruct, StructInfo},11NamedField, TypeRegistration, TypeRegistry,12};13use alloc::string::ToString;14use core::slice::Iter;15use serde::de::{Error, MapAccess, SeqAccess};1617use super::ReflectDeserializerProcessor;1819/// A helper trait for accessing type information from struct-like types.20pub(super) trait StructLikeInfo {21fn field<E: Error>(&self, name: &str) -> Result<&NamedField, E>;22fn field_at<E: Error>(&self, index: usize) -> Result<&NamedField, E>;23fn field_len(&self) -> usize;24fn iter_fields(&self) -> Iter<'_, NamedField>;25}2627impl StructLikeInfo for StructInfo {28fn field<E: Error>(&self, name: &str) -> Result<&NamedField, E> {29Self::field(self, name).ok_or_else(|| {30make_custom_error(format_args!(31"no field named `{}` on struct `{}`",32name,33self.type_path(),34))35})36}3738fn field_at<E: Error>(&self, index: usize) -> Result<&NamedField, E> {39Self::field_at(self, index).ok_or_else(|| {40make_custom_error(format_args!(41"no field at index `{}` on struct `{}`",42index,43self.type_path(),44))45})46}4748fn field_len(&self) -> usize {49Self::field_len(self)50}5152fn iter_fields(&self) -> Iter<'_, NamedField> {53self.iter()54}55}5657impl StructLikeInfo for StructVariantInfo {58fn field<E: Error>(&self, name: &str) -> Result<&NamedField, E> {59Self::field(self, name).ok_or_else(|| {60make_custom_error(format_args!(61"no field named `{}` on variant `{}`",62name,63self.name(),64))65})66}6768fn field_at<E: Error>(&self, index: usize) -> Result<&NamedField, E> {69Self::field_at(self, index).ok_or_else(|| {70make_custom_error(format_args!(71"no field at index `{}` on variant `{}`",72index,73self.name(),74))75})76}7778fn field_len(&self) -> usize {79Self::field_len(self)80}8182fn iter_fields(&self) -> Iter<'_, NamedField> {83self.iter()84}85}8687/// Deserializes a [struct-like] type from a mapping of fields, returning a [`DynamicStruct`].88///89/// [struct-like]: StructLikeInfo90pub(super) fn visit_struct<'de, T, V, P>(91map: &mut V,92info: &'static T,93registration: &TypeRegistration,94registry: &TypeRegistry,95mut processor: Option<&mut P>,96) -> Result<DynamicStruct, V::Error>97where98T: StructLikeInfo,99V: MapAccess<'de>,100P: ReflectDeserializerProcessor,101{102let mut dynamic_struct = DynamicStruct::default();103while let Some(Ident(key)) = map.next_key::<Ident>()? {104let field = info.field::<V::Error>(&key).map_err(|_| {105let fields = info.iter_fields().map(NamedField::name);106make_custom_error(format_args!(107"unknown field `{}`, expected one of {:?}",108key,109ExpectedValues::from_iter(fields)110))111})?;112let registration = try_get_registration(*field.ty(), registry)?;113let value = map.next_value_seed(TypedReflectDeserializer::new_internal(114registration,115registry,116processor.as_deref_mut(),117))?;118dynamic_struct.insert_boxed(&key, value);119}120121if let Some(serialization_data) = registration.data::<SerializationData>() {122for (skipped_index, skipped_field) in serialization_data.iter_skipped() {123let Ok(field) = info.field_at::<V::Error>(*skipped_index) else {124continue;125};126dynamic_struct.insert_boxed(127field.name(),128skipped_field.generate_default().into_partial_reflect(),129);130}131}132133Ok(dynamic_struct)134}135136/// Deserializes a [struct-like] type from a sequence of fields, returning a [`DynamicStruct`].137///138/// [struct-like]: StructLikeInfo139pub(super) fn visit_struct_seq<'de, T, V, P>(140seq: &mut V,141info: &T,142registration: &TypeRegistration,143registry: &TypeRegistry,144mut processor: Option<&mut P>,145) -> Result<DynamicStruct, V::Error>146where147T: StructLikeInfo,148V: SeqAccess<'de>,149P: ReflectDeserializerProcessor,150{151let mut dynamic_struct = DynamicStruct::default();152153let len = info.field_len();154155if len == 0 {156// Handle unit structs157return Ok(dynamic_struct);158}159160let serialization_data = registration.data::<SerializationData>();161162for index in 0..len {163let name = info.field_at::<V::Error>(index)?.name();164165if serialization_data166.map(|data| data.is_field_skipped(index))167.unwrap_or_default()168{169if let Some(value) = serialization_data.unwrap().generate_default(index) {170dynamic_struct.insert_boxed(name, value.into_partial_reflect());171}172continue;173}174175let value = seq176.next_element_seed(TypedReflectDeserializer::new_internal(177try_get_registration(*info.field_at(index)?.ty(), registry)?,178registry,179processor.as_deref_mut(),180))?181.ok_or_else(|| Error::invalid_length(index, &len.to_string().as_str()))?;182dynamic_struct.insert_boxed(name, value);183}184185Ok(dynamic_struct)186}187188189