Path: blob/main/crates/bevy_reflect/src/serde/de/struct_utils.rs
6600 views
use crate::{1serde::{2de::{3error_utils::make_custom_error,4helpers::{ExpectedValues, Ident},5registration_utils::try_get_registration,6},7SerializationData, TypedReflectDeserializer,8},9DynamicStruct, NamedField, StructInfo, StructVariantInfo, TypeRegistration, TypeRegistry,10};11use alloc::string::ToString;12use core::slice::Iter;13use serde::de::{Error, MapAccess, SeqAccess};1415use super::ReflectDeserializerProcessor;1617/// A helper trait for accessing type information from struct-like types.18pub(super) trait StructLikeInfo {19fn field<E: Error>(&self, name: &str) -> Result<&NamedField, E>;20fn field_at<E: Error>(&self, index: usize) -> Result<&NamedField, E>;21fn field_len(&self) -> usize;22fn iter_fields(&self) -> Iter<'_, NamedField>;23}2425impl StructLikeInfo for StructInfo {26fn field<E: Error>(&self, name: &str) -> Result<&NamedField, E> {27Self::field(self, name).ok_or_else(|| {28make_custom_error(format_args!(29"no field named `{}` on struct `{}`",30name,31self.type_path(),32))33})34}3536fn field_at<E: Error>(&self, index: usize) -> Result<&NamedField, E> {37Self::field_at(self, index).ok_or_else(|| {38make_custom_error(format_args!(39"no field at index `{}` on struct `{}`",40index,41self.type_path(),42))43})44}4546fn field_len(&self) -> usize {47Self::field_len(self)48}4950fn iter_fields(&self) -> Iter<'_, NamedField> {51self.iter()52}53}5455impl StructLikeInfo for StructVariantInfo {56fn field<E: Error>(&self, name: &str) -> Result<&NamedField, E> {57Self::field(self, name).ok_or_else(|| {58make_custom_error(format_args!(59"no field named `{}` on variant `{}`",60name,61self.name(),62))63})64}6566fn field_at<E: Error>(&self, index: usize) -> Result<&NamedField, E> {67Self::field_at(self, index).ok_or_else(|| {68make_custom_error(format_args!(69"no field at index `{}` on variant `{}`",70index,71self.name(),72))73})74}7576fn field_len(&self) -> usize {77Self::field_len(self)78}7980fn iter_fields(&self) -> Iter<'_, NamedField> {81self.iter()82}83}8485/// Deserializes a [struct-like] type from a mapping of fields, returning a [`DynamicStruct`].86///87/// [struct-like]: StructLikeInfo88pub(super) fn visit_struct<'de, T, V, P>(89map: &mut V,90info: &'static T,91registration: &TypeRegistration,92registry: &TypeRegistry,93mut processor: Option<&mut P>,94) -> Result<DynamicStruct, V::Error>95where96T: StructLikeInfo,97V: MapAccess<'de>,98P: ReflectDeserializerProcessor,99{100let mut dynamic_struct = DynamicStruct::default();101while let Some(Ident(key)) = map.next_key::<Ident>()? {102let field = info.field::<V::Error>(&key).map_err(|_| {103let fields = info.iter_fields().map(NamedField::name);104make_custom_error(format_args!(105"unknown field `{}`, expected one of {:?}",106key,107ExpectedValues::from_iter(fields)108))109})?;110let registration = try_get_registration(*field.ty(), registry)?;111let value = map.next_value_seed(TypedReflectDeserializer::new_internal(112registration,113registry,114processor.as_deref_mut(),115))?;116dynamic_struct.insert_boxed(&key, value);117}118119if let Some(serialization_data) = registration.data::<SerializationData>() {120for (skipped_index, skipped_field) in serialization_data.iter_skipped() {121let Ok(field) = info.field_at::<V::Error>(*skipped_index) else {122continue;123};124dynamic_struct.insert_boxed(125field.name(),126skipped_field.generate_default().into_partial_reflect(),127);128}129}130131Ok(dynamic_struct)132}133134/// Deserializes a [struct-like] type from a sequence of fields, returning a [`DynamicStruct`].135///136/// [struct-like]: StructLikeInfo137pub(super) fn visit_struct_seq<'de, T, V, P>(138seq: &mut V,139info: &T,140registration: &TypeRegistration,141registry: &TypeRegistry,142mut processor: Option<&mut P>,143) -> Result<DynamicStruct, V::Error>144where145T: StructLikeInfo,146V: SeqAccess<'de>,147P: ReflectDeserializerProcessor,148{149let mut dynamic_struct = DynamicStruct::default();150151let len = info.field_len();152153if len == 0 {154// Handle unit structs155return Ok(dynamic_struct);156}157158let serialization_data = registration.data::<SerializationData>();159160for index in 0..len {161let name = info.field_at::<V::Error>(index)?.name();162163if serialization_data164.map(|data| data.is_field_skipped(index))165.unwrap_or_default()166{167if let Some(value) = serialization_data.unwrap().generate_default(index) {168dynamic_struct.insert_boxed(name, value.into_partial_reflect());169}170continue;171}172173let value = seq174.next_element_seed(TypedReflectDeserializer::new_internal(175try_get_registration(*info.field_at(index)?.ty(), registry)?,176registry,177processor.as_deref_mut(),178))?179.ok_or_else(|| Error::invalid_length(index, &len.to_string().as_str()))?;180dynamic_struct.insert_boxed(name, value);181}182183Ok(dynamic_struct)184}185186187