bevy_reflect/serde/de/
enums.rs

1use 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};
15use core::{fmt, fmt::Formatter};
16use serde::de::{DeserializeSeed, EnumAccess, Error, MapAccess, SeqAccess, VariantAccess, Visitor};
17
18use super::ReflectDeserializerProcessor;
19
20/// A [`Visitor`] for deserializing [`Enum`] values.
21///
22/// [`Enum`]: crate::Enum
23pub(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
30impl<'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
96struct VariantDeserializer {
97    enum_info: &'static EnumInfo,
98}
99
100impl<'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
148struct StructVariantVisitor<'a, P> {
149    struct_info: &'static StructVariantInfo,
150    registration: &'a TypeRegistration,
151    registry: &'a TypeRegistry,
152    processor: Option<&'a mut P>,
153}
154
155impl<'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
189struct TupleVariantVisitor<'a, P> {
190    tuple_info: &'static TupleVariantInfo,
191    registration: &'a TypeRegistration,
192    registry: &'a TypeRegistry,
193    processor: Option<&'a mut P>,
194}
195
196impl<'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}