Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_reflect/src/serde/de/options.rs
6600 views
1
use crate::{
2
serde::{
3
de::{error_utils::make_custom_error, registration_utils::try_get_registration},
4
TypedReflectDeserializer,
5
},
6
DynamicEnum, DynamicTuple, EnumInfo, TypeRegistry, VariantInfo,
7
};
8
use core::{fmt, fmt::Formatter};
9
use serde::de::{DeserializeSeed, Error, Visitor};
10
11
use super::ReflectDeserializerProcessor;
12
13
/// A [`Visitor`] for deserializing [`Option`] values.
14
pub(super) struct OptionVisitor<'a, P> {
15
pub enum_info: &'static EnumInfo,
16
pub registry: &'a TypeRegistry,
17
pub processor: Option<&'a mut P>,
18
}
19
20
impl<'de, P: ReflectDeserializerProcessor> Visitor<'de> for OptionVisitor<'_, P> {
21
type Value = DynamicEnum;
22
23
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
24
formatter.write_str("reflected option value of type ")?;
25
formatter.write_str(self.enum_info.type_path())
26
}
27
28
fn visit_none<E>(self) -> Result<Self::Value, E>
29
where
30
E: Error,
31
{
32
let mut option = DynamicEnum::default();
33
option.set_variant("None", ());
34
Ok(option)
35
}
36
37
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
38
where
39
D: serde::Deserializer<'de>,
40
{
41
let variant_info = self.enum_info.variant("Some").unwrap();
42
match variant_info {
43
VariantInfo::Tuple(tuple_info) if tuple_info.field_len() == 1 => {
44
let field = tuple_info.field_at(0).unwrap();
45
let registration = try_get_registration(*field.ty(), self.registry)?;
46
let de = TypedReflectDeserializer::new_internal(
47
registration,
48
self.registry,
49
self.processor,
50
);
51
let mut value = DynamicTuple::default();
52
value.insert_boxed(de.deserialize(deserializer)?);
53
let mut option = DynamicEnum::default();
54
option.set_variant("Some", value);
55
Ok(option)
56
}
57
info => Err(make_custom_error(format_args!(
58
"invalid variant, expected `Some` but got `{}`",
59
info.name()
60
))),
61
}
62
}
63
}
64
65