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