bevy_reflect/serde/ser/
serializer.rs

1#[cfg(feature = "debug_stack")]
2use crate::serde::ser::error_utils::TYPE_INFO_STACK;
3use crate::{
4    serde::ser::{
5        arrays::ArraySerializer, custom_serialization::try_custom_serialize, enums::EnumSerializer,
6        error_utils::make_custom_error, lists::ListSerializer, maps::MapSerializer,
7        sets::SetSerializer, structs::StructSerializer, tuple_structs::TupleStructSerializer,
8        tuples::TupleSerializer,
9    },
10    PartialReflect, ReflectRef, TypeRegistry,
11};
12use serde::{ser::SerializeMap, Serialize, Serializer};
13
14use super::ReflectSerializerProcessor;
15
16/// A general purpose serializer for reflected types.
17///
18/// This is the serializer counterpart to [`ReflectDeserializer`].
19///
20/// See [`TypedReflectSerializer`] for a serializer that serializes a known type.
21///
22/// # Output
23///
24/// This serializer will output a map with a single entry,
25/// where the key is the _full_ [type path] of the reflected type
26/// and the value is the serialized data.
27///
28/// If you want to override serialization for specific values, you can pass in
29/// a reference to a [`ReflectSerializerProcessor`] which will take priority
30/// over all other serialization methods - see [`with_processor`].
31///
32/// # Example
33///
34/// ```
35/// # use bevy_reflect::prelude::*;
36/// # use bevy_reflect::{TypeRegistry, serde::ReflectSerializer};
37/// #[derive(Reflect, PartialEq, Debug)]
38/// #[type_path = "my_crate"]
39/// struct MyStruct {
40///   value: i32
41/// }
42///
43/// let mut registry = TypeRegistry::default();
44/// registry.register::<MyStruct>();
45///
46/// let input = MyStruct { value: 123 };
47///
48/// let reflect_serializer = ReflectSerializer::new(&input, &registry);
49/// let output = ron::to_string(&reflect_serializer).unwrap();
50///
51/// assert_eq!(output, r#"{"my_crate::MyStruct":(value:123)}"#);
52/// ```
53///
54/// [`ReflectDeserializer`]: crate::serde::ReflectDeserializer
55/// [type path]: crate::TypePath::type_path
56/// [`with_processor`]: Self::with_processor
57pub struct ReflectSerializer<'a, P = ()> {
58    value: &'a dyn PartialReflect,
59    registry: &'a TypeRegistry,
60    processor: Option<&'a P>,
61}
62
63impl<'a> ReflectSerializer<'a, ()> {
64    /// Creates a serializer with no processor.
65    ///
66    /// If you want to add custom logic for serializing certain values, use
67    /// [`with_processor`].
68    ///
69    /// [`with_processor`]: Self::with_processor
70    pub fn new(value: &'a dyn PartialReflect, registry: &'a TypeRegistry) -> Self {
71        Self {
72            value,
73            registry,
74            processor: None,
75        }
76    }
77}
78
79impl<'a, P: ReflectSerializerProcessor> ReflectSerializer<'a, P> {
80    /// Creates a serializer with a processor.
81    ///
82    /// If you do not need any custom logic for handling certain values, use
83    /// [`new`].
84    ///
85    /// [`new`]: Self::new
86    pub fn with_processor(
87        value: &'a dyn PartialReflect,
88        registry: &'a TypeRegistry,
89        processor: &'a P,
90    ) -> Self {
91        Self {
92            value,
93            registry,
94            processor: Some(processor),
95        }
96    }
97}
98
99impl<P: ReflectSerializerProcessor> Serialize for ReflectSerializer<'_, P> {
100    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
101    where
102        S: Serializer,
103    {
104        let mut state = serializer.serialize_map(Some(1))?;
105        state.serialize_entry(
106            self.value
107                .get_represented_type_info()
108                .ok_or_else(|| {
109                    if self.value.is_dynamic() {
110                        make_custom_error(format_args!(
111                            "cannot serialize dynamic value without represented type: `{}`",
112                            self.value.reflect_type_path()
113                        ))
114                    } else {
115                        make_custom_error(format_args!(
116                            "cannot get type info for `{}`",
117                            self.value.reflect_type_path()
118                        ))
119                    }
120                })?
121                .type_path(),
122            &TypedReflectSerializer::new_internal(self.value, self.registry, self.processor),
123        )?;
124        state.end()
125    }
126}
127
128/// A serializer for reflected types whose type will be known during deserialization.
129///
130/// This is the serializer counterpart to [`TypedReflectDeserializer`].
131///
132/// See [`ReflectSerializer`] for a serializer that serializes an unknown type.
133///
134/// # Output
135///
136/// Since the type is expected to be known during deserialization,
137/// this serializer will not output any additional type information,
138/// such as the [type path].
139///
140/// Instead, it will output just the serialized data.
141///
142/// If you want to override serialization for specific values, you can pass in
143/// a reference to a [`ReflectSerializerProcessor`] which will take priority
144/// over all other serialization methods - see [`with_processor`].
145///
146/// # Example
147///
148/// ```
149/// # use bevy_reflect::prelude::*;
150/// # use bevy_reflect::{TypeRegistry, serde::TypedReflectSerializer};
151/// #[derive(Reflect, PartialEq, Debug)]
152/// #[type_path = "my_crate"]
153/// struct MyStruct {
154///   value: i32
155/// }
156///
157/// let mut registry = TypeRegistry::default();
158/// registry.register::<MyStruct>();
159///
160/// let input = MyStruct { value: 123 };
161///
162/// let reflect_serializer = TypedReflectSerializer::new(&input, &registry);
163/// let output = ron::to_string(&reflect_serializer).unwrap();
164///
165/// assert_eq!(output, r#"(value:123)"#);
166/// ```
167///
168/// [`TypedReflectDeserializer`]: crate::serde::TypedReflectDeserializer
169/// [type path]: crate::TypePath::type_path
170/// [`with_processor`]: Self::with_processor
171pub struct TypedReflectSerializer<'a, P = ()> {
172    value: &'a dyn PartialReflect,
173    registry: &'a TypeRegistry,
174    processor: Option<&'a P>,
175}
176
177impl<'a> TypedReflectSerializer<'a, ()> {
178    /// Creates a serializer with no processor.
179    ///
180    /// If you want to add custom logic for serializing certain values, use
181    /// [`with_processor`].
182    ///
183    /// [`with_processor`]: Self::with_processor
184    pub fn new(value: &'a dyn PartialReflect, registry: &'a TypeRegistry) -> Self {
185        #[cfg(feature = "debug_stack")]
186        TYPE_INFO_STACK.set(crate::type_info_stack::TypeInfoStack::new());
187
188        Self {
189            value,
190            registry,
191            processor: None,
192        }
193    }
194}
195
196impl<'a, P> TypedReflectSerializer<'a, P> {
197    /// Creates a serializer with a processor.
198    ///
199    /// If you do not need any custom logic for handling certain values, use
200    /// [`new`].
201    ///
202    /// [`new`]: Self::new
203    pub fn with_processor(
204        value: &'a dyn PartialReflect,
205        registry: &'a TypeRegistry,
206        processor: &'a P,
207    ) -> Self {
208        #[cfg(feature = "debug_stack")]
209        TYPE_INFO_STACK.set(crate::type_info_stack::TypeInfoStack::new());
210
211        Self {
212            value,
213            registry,
214            processor: Some(processor),
215        }
216    }
217
218    /// An internal constructor for creating a serializer without resetting the type info stack.
219    pub(super) fn new_internal(
220        value: &'a dyn PartialReflect,
221        registry: &'a TypeRegistry,
222        processor: Option<&'a P>,
223    ) -> Self {
224        Self {
225            value,
226            registry,
227            processor,
228        }
229    }
230}
231
232impl<P: ReflectSerializerProcessor> Serialize for TypedReflectSerializer<'_, P> {
233    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
234    where
235        S: Serializer,
236    {
237        #[cfg(feature = "debug_stack")]
238        {
239            if let Some(info) = self.value.get_represented_type_info() {
240                TYPE_INFO_STACK.with_borrow_mut(|stack| stack.push(info));
241            }
242        }
243
244        // First, check if our processor wants to serialize this type
245        // This takes priority over any other serialization operations
246        let serializer = if let Some(processor) = self.processor {
247            match processor.try_serialize(self.value, self.registry, serializer) {
248                Ok(Ok(value)) => {
249                    return Ok(value);
250                }
251                Err(err) => {
252                    return Err(make_custom_error(err));
253                }
254                Ok(Err(serializer)) => serializer,
255            }
256        } else {
257            serializer
258        };
259
260        // Handle both Value case and types that have a custom `Serialize`
261        let (serializer, error) = match try_custom_serialize(self.value, self.registry, serializer)
262        {
263            Ok(result) => return result,
264            Err(value) => value,
265        };
266
267        let output = match self.value.reflect_ref() {
268            ReflectRef::Struct(struct_value) => StructSerializer {
269                struct_value,
270                registry: self.registry,
271                processor: self.processor,
272            }
273            .serialize(serializer),
274            ReflectRef::TupleStruct(tuple_struct) => TupleStructSerializer {
275                tuple_struct,
276                registry: self.registry,
277                processor: self.processor,
278            }
279            .serialize(serializer),
280            ReflectRef::Tuple(tuple) => TupleSerializer {
281                tuple,
282                registry: self.registry,
283                processor: self.processor,
284            }
285            .serialize(serializer),
286            ReflectRef::List(list) => ListSerializer {
287                list,
288                registry: self.registry,
289                processor: self.processor,
290            }
291            .serialize(serializer),
292            ReflectRef::Array(array) => ArraySerializer {
293                array,
294                registry: self.registry,
295                processor: self.processor,
296            }
297            .serialize(serializer),
298            ReflectRef::Map(map) => MapSerializer {
299                map,
300                registry: self.registry,
301                processor: self.processor,
302            }
303            .serialize(serializer),
304            ReflectRef::Set(set) => SetSerializer {
305                set,
306                registry: self.registry,
307                processor: self.processor,
308            }
309            .serialize(serializer),
310            ReflectRef::Enum(enum_value) => EnumSerializer {
311                enum_value,
312                registry: self.registry,
313                processor: self.processor,
314            }
315            .serialize(serializer),
316            #[cfg(feature = "functions")]
317            ReflectRef::Function(_) => Err(make_custom_error("functions cannot be serialized")),
318            ReflectRef::Opaque(_) => Err(error),
319        };
320
321        #[cfg(feature = "debug_stack")]
322        TYPE_INFO_STACK.with_borrow_mut(crate::type_info_stack::TypeInfoStack::pop);
323
324        output
325    }
326}