Skip to main content

bevy_reflect/serde/de/
enums.rs

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