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, ®istry);
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, ®istry);
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}