Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_reflect/src/serde/de/tuple_utils.rs
6600 views
1
use crate::{
2
serde::{
3
de::{error_utils::make_custom_error, registration_utils::try_get_registration},
4
SerializationData, TypedReflectDeserializer,
5
},
6
DynamicTuple, TupleInfo, TupleStructInfo, TupleVariantInfo, TypeRegistration, TypeRegistry,
7
UnnamedField,
8
};
9
use alloc::string::ToString;
10
use serde::de::{Error, SeqAccess};
11
12
use super::ReflectDeserializerProcessor;
13
14
pub(super) trait TupleLikeInfo {
15
fn field_at<E: Error>(&self, index: usize) -> Result<&UnnamedField, E>;
16
fn field_len(&self) -> usize;
17
}
18
19
impl TupleLikeInfo for TupleInfo {
20
fn field_len(&self) -> usize {
21
Self::field_len(self)
22
}
23
24
fn field_at<E: Error>(&self, index: usize) -> Result<&UnnamedField, E> {
25
Self::field_at(self, index).ok_or_else(|| {
26
make_custom_error(format_args!(
27
"no field at index `{}` on tuple `{}`",
28
index,
29
self.type_path(),
30
))
31
})
32
}
33
}
34
35
impl TupleLikeInfo for TupleStructInfo {
36
fn field_len(&self) -> usize {
37
Self::field_len(self)
38
}
39
40
fn field_at<E: Error>(&self, index: usize) -> Result<&UnnamedField, E> {
41
Self::field_at(self, index).ok_or_else(|| {
42
make_custom_error(format_args!(
43
"no field at index `{}` on tuple struct `{}`",
44
index,
45
self.type_path(),
46
))
47
})
48
}
49
}
50
51
impl TupleLikeInfo for TupleVariantInfo {
52
fn field_len(&self) -> usize {
53
Self::field_len(self)
54
}
55
56
fn field_at<E: Error>(&self, index: usize) -> Result<&UnnamedField, E> {
57
Self::field_at(self, index).ok_or_else(|| {
58
make_custom_error(format_args!(
59
"no field at index `{}` on tuple variant `{}`",
60
index,
61
self.name(),
62
))
63
})
64
}
65
}
66
67
/// Deserializes a [tuple-like] type from a sequence of elements, returning a [`DynamicTuple`].
68
///
69
/// [tuple-like]: TupleLikeInfo
70
pub(super) fn visit_tuple<'de, T, V, P>(
71
seq: &mut V,
72
info: &T,
73
registration: &TypeRegistration,
74
registry: &TypeRegistry,
75
mut processor: Option<&mut P>,
76
) -> Result<DynamicTuple, V::Error>
77
where
78
T: TupleLikeInfo,
79
V: SeqAccess<'de>,
80
P: ReflectDeserializerProcessor,
81
{
82
let mut tuple = DynamicTuple::default();
83
84
let len = info.field_len();
85
86
if len == 0 {
87
// Handle empty tuple/tuple struct
88
return Ok(tuple);
89
}
90
91
let serialization_data = registration.data::<SerializationData>();
92
93
for index in 0..len {
94
if let Some(value) = serialization_data.and_then(|data| data.generate_default(index)) {
95
tuple.insert_boxed(value.into_partial_reflect());
96
continue;
97
}
98
99
let value = seq
100
.next_element_seed(TypedReflectDeserializer::new_internal(
101
try_get_registration(*info.field_at(index)?.ty(), registry)?,
102
registry,
103
processor.as_deref_mut(),
104
))?
105
.ok_or_else(|| Error::invalid_length(index, &len.to_string().as_str()))?;
106
tuple.insert_boxed(value);
107
}
108
109
Ok(tuple)
110
}
111
112