Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_reflect/src/serde/de/enums.rs
6600 views
1
use crate::{
2
serde::{
3
de::{
4
error_utils::make_custom_error,
5
helpers::ExpectedValues,
6
registration_utils::try_get_registration,
7
struct_utils::{visit_struct, visit_struct_seq},
8
tuple_utils::{visit_tuple, TupleLikeInfo},
9
},
10
TypedReflectDeserializer,
11
},
12
DynamicEnum, DynamicStruct, DynamicTuple, DynamicVariant, EnumInfo, StructVariantInfo,
13
TupleVariantInfo, TypeRegistration, TypeRegistry, VariantInfo,
14
};
15
use core::{fmt, fmt::Formatter};
16
use serde::de::{DeserializeSeed, EnumAccess, Error, MapAccess, SeqAccess, VariantAccess, Visitor};
17
18
use super::ReflectDeserializerProcessor;
19
20
/// A [`Visitor`] for deserializing [`Enum`] values.
21
///
22
/// [`Enum`]: crate::Enum
23
pub(super) struct EnumVisitor<'a, P> {
24
pub enum_info: &'static EnumInfo,
25
pub registration: &'a TypeRegistration,
26
pub registry: &'a TypeRegistry,
27
pub processor: Option<&'a mut P>,
28
}
29
30
impl<'de, P: ReflectDeserializerProcessor> Visitor<'de> for EnumVisitor<'_, P> {
31
type Value = DynamicEnum;
32
33
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
34
formatter.write_str("reflected enum value")
35
}
36
37
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
38
where
39
A: EnumAccess<'de>,
40
{
41
let mut dynamic_enum = DynamicEnum::default();
42
let (variant_info, variant) = data.variant_seed(VariantDeserializer {
43
enum_info: self.enum_info,
44
})?;
45
46
let value: DynamicVariant = match variant_info {
47
VariantInfo::Unit(..) => variant.unit_variant()?.into(),
48
VariantInfo::Struct(struct_info) => variant
49
.struct_variant(
50
struct_info.field_names(),
51
StructVariantVisitor {
52
struct_info,
53
registration: self.registration,
54
registry: self.registry,
55
processor: self.processor,
56
},
57
)?
58
.into(),
59
VariantInfo::Tuple(tuple_info) if tuple_info.field_len() == 1 => {
60
let registration = try_get_registration(
61
*TupleLikeInfo::field_at(tuple_info, 0)?.ty(),
62
self.registry,
63
)?;
64
let value =
65
variant.newtype_variant_seed(TypedReflectDeserializer::new_internal(
66
registration,
67
self.registry,
68
self.processor,
69
))?;
70
let mut dynamic_tuple = DynamicTuple::default();
71
dynamic_tuple.insert_boxed(value);
72
dynamic_tuple.into()
73
}
74
VariantInfo::Tuple(tuple_info) => variant
75
.tuple_variant(
76
tuple_info.field_len(),
77
TupleVariantVisitor {
78
tuple_info,
79
registration: self.registration,
80
registry: self.registry,
81
processor: self.processor,
82
},
83
)?
84
.into(),
85
};
86
let variant_name = variant_info.name();
87
let variant_index = self
88
.enum_info
89
.index_of(variant_name)
90
.expect("variant should exist");
91
dynamic_enum.set_variant_with_index(variant_index, variant_name, value);
92
Ok(dynamic_enum)
93
}
94
}
95
96
struct VariantDeserializer {
97
enum_info: &'static EnumInfo,
98
}
99
100
impl<'de> DeserializeSeed<'de> for VariantDeserializer {
101
type Value = &'static VariantInfo;
102
103
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
104
where
105
D: serde::Deserializer<'de>,
106
{
107
struct VariantVisitor(&'static EnumInfo);
108
109
impl<'de> Visitor<'de> for VariantVisitor {
110
type Value = &'static VariantInfo;
111
112
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
113
formatter.write_str("expected either a variant index or variant name")
114
}
115
116
fn visit_u32<E>(self, variant_index: u32) -> Result<Self::Value, E>
117
where
118
E: Error,
119
{
120
self.0.variant_at(variant_index as usize).ok_or_else(|| {
121
make_custom_error(format_args!(
122
"no variant found at index `{}` on enum `{}`",
123
variant_index,
124
self.0.type_path()
125
))
126
})
127
}
128
129
fn visit_str<E>(self, variant_name: &str) -> Result<Self::Value, E>
130
where
131
E: Error,
132
{
133
self.0.variant(variant_name).ok_or_else(|| {
134
let names = self.0.iter().map(VariantInfo::name);
135
make_custom_error(format_args!(
136
"unknown variant `{}`, expected one of {:?}",
137
variant_name,
138
ExpectedValues::from_iter(names)
139
))
140
})
141
}
142
}
143
144
deserializer.deserialize_identifier(VariantVisitor(self.enum_info))
145
}
146
}
147
148
struct StructVariantVisitor<'a, P> {
149
struct_info: &'static StructVariantInfo,
150
registration: &'a TypeRegistration,
151
registry: &'a TypeRegistry,
152
processor: Option<&'a mut P>,
153
}
154
155
impl<'de, P: ReflectDeserializerProcessor> Visitor<'de> for StructVariantVisitor<'_, P> {
156
type Value = DynamicStruct;
157
158
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
159
formatter.write_str("reflected struct variant value")
160
}
161
162
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
163
where
164
A: SeqAccess<'de>,
165
{
166
visit_struct_seq(
167
&mut seq,
168
self.struct_info,
169
self.registration,
170
self.registry,
171
self.processor,
172
)
173
}
174
175
fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error>
176
where
177
V: MapAccess<'de>,
178
{
179
visit_struct(
180
&mut map,
181
self.struct_info,
182
self.registration,
183
self.registry,
184
self.processor,
185
)
186
}
187
}
188
189
struct TupleVariantVisitor<'a, P> {
190
tuple_info: &'static TupleVariantInfo,
191
registration: &'a TypeRegistration,
192
registry: &'a TypeRegistry,
193
processor: Option<&'a mut P>,
194
}
195
196
impl<'de, P: ReflectDeserializerProcessor> Visitor<'de> for TupleVariantVisitor<'_, P> {
197
type Value = DynamicTuple;
198
199
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
200
formatter.write_str("reflected tuple variant value")
201
}
202
203
fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
204
where
205
V: SeqAccess<'de>,
206
{
207
visit_tuple(
208
&mut seq,
209
self.tuple_info,
210
self.registration,
211
self.registry,
212
self.processor,
213
)
214
}
215
}
216
217