1mod de;
4mod ser;
5mod type_data;
6
7pub use de::*;
8pub use ser::*;
9pub use type_data::*;
10
11#[cfg(test)]
12mod tests {
13 use super::*;
14 use crate::{
15 structs::{DynamicStruct, Struct},
16 tuple_struct::DynamicTupleStruct,
17 type_registry::TypeRegistry,
18 FromReflect, PartialReflect, Reflect,
19 };
20 use serde::de::DeserializeSeed;
21
22 #[test]
23 fn test_serialization_struct() {
24 #[derive(Debug, Reflect, PartialEq)]
25 #[reflect(PartialEq)]
26 struct TestStruct {
27 a: i32,
28 #[reflect(ignore)]
29 b: i32,
30 #[reflect(skip_serializing)]
31 c: i32,
32 #[reflect(skip_serializing)]
33 #[reflect(default = "custom_default")]
34 d: i32,
35 e: i32,
36 }
37
38 fn custom_default() -> i32 {
39 -1
40 }
41
42 let mut registry = TypeRegistry::default();
43 registry.register::<TestStruct>();
44
45 let test_struct = TestStruct {
46 a: 3,
47 b: 4,
48 c: 5,
49 d: 6,
50 e: 7,
51 };
52
53 let serializer = ReflectSerializer::new(&test_struct, ®istry);
54 let serialized =
55 ron::ser::to_string_pretty(&serializer, ron::ser::PrettyConfig::default()).unwrap();
56
57 let mut deserializer = ron::de::Deserializer::from_str(&serialized).unwrap();
58 let reflect_deserializer = ReflectDeserializer::new(®istry);
59 let deserialized = reflect_deserializer.deserialize(&mut deserializer).unwrap();
60
61 let mut expected = DynamicStruct::default();
62 expected.insert("a", 3);
63 expected.insert("c", 0);
65 expected.insert("d", -1);
66 expected.insert("e", 7);
67
68 assert!(
69 expected
70 .reflect_partial_eq(deserialized.as_partial_reflect())
71 .unwrap(),
72 "Deserialization failed: expected {expected:?} found {deserialized:?}"
73 );
74
75 let expected = TestStruct {
76 a: 3,
77 b: 0,
78 c: 0,
79 d: -1,
80 e: 7,
81 };
82 let received =
83 <TestStruct as FromReflect>::from_reflect(deserialized.as_partial_reflect()).unwrap();
84
85 assert_eq!(
86 expected, received,
87 "FromReflect failed: expected {expected:?} found {received:?}"
88 );
89 }
90
91 #[test]
92 fn test_serialization_tuple_struct() {
93 #[derive(Debug, Reflect, PartialEq)]
94 #[reflect(PartialEq)]
95 struct TestStruct(
96 i32,
97 #[reflect(ignore)] i32,
98 #[reflect(skip_serializing)] i32,
99 #[reflect(skip_serializing)]
100 #[reflect(default = "custom_default")]
101 i32,
102 i32,
103 );
104
105 fn custom_default() -> i32 {
106 -1
107 }
108
109 let mut registry = TypeRegistry::default();
110 registry.register::<TestStruct>();
111
112 let test_struct = TestStruct(3, 4, 5, 6, 7);
113
114 let serializer = ReflectSerializer::new(&test_struct, ®istry);
115 let serialized =
116 ron::ser::to_string_pretty(&serializer, ron::ser::PrettyConfig::default()).unwrap();
117
118 let mut deserializer = ron::de::Deserializer::from_str(&serialized).unwrap();
119 let reflect_deserializer = ReflectDeserializer::new(®istry);
120 let deserialized = reflect_deserializer.deserialize(&mut deserializer).unwrap();
121
122 let mut expected = DynamicTupleStruct::default();
123 expected.insert(3);
124 expected.insert(0);
126 expected.insert(-1);
127 expected.insert(7);
128
129 assert!(
130 expected
131 .reflect_partial_eq(deserialized.as_partial_reflect())
132 .unwrap(),
133 "Deserialization failed: expected {expected:?} found {deserialized:?}"
134 );
135
136 let expected = TestStruct(3, 0, 0, -1, 7);
137 let received =
138 <TestStruct as FromReflect>::from_reflect(deserialized.as_partial_reflect()).unwrap();
139
140 assert_eq!(
141 expected, received,
142 "FromReflect failed: expected {expected:?} found {received:?}"
143 );
144 }
145
146 #[test]
147 #[should_panic(
148 expected = "cannot serialize dynamic value without represented type: `bevy_reflect::DynamicStruct`"
149 )]
150 fn should_not_serialize_unproxied_dynamic() {
151 let registry = TypeRegistry::default();
152
153 let mut value = DynamicStruct::default();
154 value.insert("foo", 123_u32);
155
156 let serializer = ReflectSerializer::new(&value, ®istry);
157 ron::ser::to_string(&serializer).unwrap();
158 }
159
160 #[test]
161 fn should_roundtrip_proxied_dynamic() {
162 #[derive(Reflect)]
163 struct TestStruct {
164 a: i32,
165 b: i32,
166 }
167
168 let mut registry = TypeRegistry::default();
169 registry.register::<TestStruct>();
170
171 let value: DynamicStruct = TestStruct { a: 123, b: 456 }.to_dynamic_struct();
172
173 let serializer = ReflectSerializer::new(&value, ®istry);
174
175 let expected = r#"{"bevy_reflect::serde::tests::TestStruct":(a:123,b:456)}"#;
176 let result = ron::ser::to_string(&serializer).unwrap();
177 assert_eq!(expected, result);
178
179 let mut deserializer = ron::de::Deserializer::from_str(&result).unwrap();
180 let reflect_deserializer = ReflectDeserializer::new(®istry);
181
182 let expected = value.to_dynamic();
183 let result = reflect_deserializer.deserialize(&mut deserializer).unwrap();
184
185 assert!(expected
186 .reflect_partial_eq(result.as_partial_reflect())
187 .unwrap());
188 }
189
190 mod type_data {
191 use super::*;
192 use crate::from_reflect::FromReflect;
193 use crate::serde::{DeserializeWithRegistry, ReflectDeserializeWithRegistry};
194 use crate::serde::{ReflectSerializeWithRegistry, SerializeWithRegistry};
195 use crate::{ReflectFromReflect, TypePath};
196 use alloc::{format, string::String, vec, vec::Vec};
197 use bevy_platform::sync::Arc;
198 use bevy_reflect_derive::reflect_trait;
199 use core::any::TypeId;
200 use core::fmt::{Debug, Formatter};
201 use serde::de::{SeqAccess, Visitor};
202 use serde::ser::SerializeSeq;
203 use serde::{Deserializer, Serialize, Serializer};
204
205 #[reflect_trait]
206 trait Enemy: Reflect + Debug {
207 #[expect(dead_code, reason = "this method is purely for testing purposes")]
208 fn hp(&self) -> u8;
209 }
210
211 impl TypePath for dyn Enemy {
213 fn type_path() -> &'static str {
214 "dyn bevy_reflect::serde::tests::type_data::Enemy"
215 }
216
217 fn short_type_path() -> &'static str {
218 "dyn Enemy"
219 }
220 }
221
222 #[derive(Reflect, Debug)]
223 #[reflect(Enemy)]
224 struct Skeleton(u8);
225
226 impl Enemy for Skeleton {
227 fn hp(&self) -> u8 {
228 self.0
229 }
230 }
231
232 #[derive(Reflect, Debug)]
233 #[reflect(Enemy)]
234 struct Zombie {
235 health: u8,
236 walk_speed: f32,
237 }
238
239 impl Enemy for Zombie {
240 fn hp(&self) -> u8 {
241 self.health
242 }
243 }
244
245 #[derive(Reflect, Debug)]
246 struct Level {
247 name: String,
248 enemies: EnemyList,
249 }
250
251 #[derive(Reflect, Debug)]
252 #[reflect(SerializeWithRegistry, DeserializeWithRegistry)]
253 struct EnemyList(Vec<Arc<dyn Enemy>>);
256
257 impl SerializeWithRegistry for EnemyList {
258 fn serialize<S>(
259 &self,
260 serializer: S,
261 registry: &TypeRegistry,
262 ) -> Result<S::Ok, S::Error>
263 where
264 S: Serializer,
265 {
266 let mut state = serializer.serialize_seq(Some(self.0.len()))?;
267 for enemy in &self.0 {
268 state.serialize_element(&ReflectSerializer::new(
269 (**enemy).as_partial_reflect(),
270 registry,
271 ))?;
272 }
273 state.end()
274 }
275 }
276
277 impl<'de> DeserializeWithRegistry<'de> for EnemyList {
278 fn deserialize<D>(deserializer: D, registry: &TypeRegistry) -> Result<Self, D::Error>
279 where
280 D: Deserializer<'de>,
281 {
282 struct EnemyListVisitor<'a> {
283 registry: &'a TypeRegistry,
284 }
285
286 impl<'a, 'de> Visitor<'de> for EnemyListVisitor<'a> {
287 type Value = Vec<Arc<dyn Enemy>>;
288
289 fn expecting(&self, formatter: &mut Formatter) -> core::fmt::Result {
290 write!(formatter, "a list of enemies")
291 }
292
293 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
294 where
295 A: SeqAccess<'de>,
296 {
297 let mut enemies = Vec::new();
298 while let Some(enemy) =
299 seq.next_element_seed(ReflectDeserializer::new(self.registry))?
300 {
301 let registration = self
302 .registry
303 .get_with_type_path(
304 enemy.get_represented_type_info().unwrap().type_path(),
305 )
306 .unwrap();
307
308 let enemy = registration
310 .data::<ReflectFromReflect>()
311 .unwrap()
312 .from_reflect(&*enemy)
313 .unwrap();
314
315 let enemy = registration
317 .data::<ReflectEnemy>()
318 .unwrap()
319 .get_boxed(enemy)
320 .unwrap();
321
322 enemies.push(enemy.into());
323 }
324
325 Ok(enemies)
326 }
327 }
328
329 deserializer
330 .deserialize_seq(EnemyListVisitor { registry })
331 .map(EnemyList)
332 }
333 }
334
335 fn create_registry() -> TypeRegistry {
336 let mut registry = TypeRegistry::default();
337 registry.register::<Level>();
338 registry.register::<EnemyList>();
339 registry.register::<Skeleton>();
340 registry.register::<Zombie>();
341 registry
342 }
343
344 fn create_arc_dyn_enemy<T: Enemy>(enemy: T) -> Arc<dyn Enemy> {
345 let arc = Arc::new(enemy);
346
347 #[cfg(not(target_has_atomic = "ptr"))]
348 #[expect(
349 unsafe_code,
350 reason = "unsized coercion is an unstable feature for non-std types"
351 )]
352 let arc = unsafe { Arc::from_raw(Arc::into_raw(arc) as *const dyn Enemy) };
356
357 arc
358 }
359
360 #[test]
361 fn should_serialize_with_serialize_with_registry() {
362 let registry = create_registry();
363
364 let level = Level {
365 name: String::from("Level 1"),
366 enemies: EnemyList(vec![
367 create_arc_dyn_enemy(Skeleton(10)),
368 create_arc_dyn_enemy(Zombie {
369 health: 20,
370 walk_speed: 0.5,
371 }),
372 ]),
373 };
374
375 let serializer = ReflectSerializer::new(&level, ®istry);
376 let serialized = ron::ser::to_string(&serializer).unwrap();
377
378 let expected = r#"{"bevy_reflect::serde::tests::type_data::Level":(name:"Level 1",enemies:[{"bevy_reflect::serde::tests::type_data::Skeleton":(10)},{"bevy_reflect::serde::tests::type_data::Zombie":(health:20,walk_speed:0.5)}])}"#;
379
380 assert_eq!(expected, serialized);
381 }
382
383 #[test]
384 fn should_deserialize_with_deserialize_with_registry() {
385 let registry = create_registry();
386
387 let input = r#"{"bevy_reflect::serde::tests::type_data::Level":(name:"Level 1",enemies:[{"bevy_reflect::serde::tests::type_data::Skeleton":(10)},{"bevy_reflect::serde::tests::type_data::Zombie":(health:20,walk_speed:0.5)}])}"#;
388
389 let mut deserializer = ron::de::Deserializer::from_str(input).unwrap();
390 let reflect_deserializer = ReflectDeserializer::new(®istry);
391 let value = reflect_deserializer.deserialize(&mut deserializer).unwrap();
392
393 let output = Level::from_reflect(&*value).unwrap();
394
395 let expected = Level {
396 name: String::from("Level 1"),
397 enemies: EnemyList(vec![
398 create_arc_dyn_enemy(Skeleton(10)),
399 create_arc_dyn_enemy(Zombie {
400 health: 20,
401 walk_speed: 0.5,
402 }),
403 ]),
404 };
405
406 assert_eq!(format!("{expected:?}"), format!("{output:?}",));
408
409 let unexpected = Level {
410 name: String::from("Level 1"),
411 enemies: EnemyList(vec![
412 create_arc_dyn_enemy(Skeleton(20)),
413 create_arc_dyn_enemy(Zombie {
414 health: 20,
415 walk_speed: 5.0,
416 }),
417 ]),
418 };
419
420 assert_ne!(format!("{unexpected:?}"), format!("{output:?}"));
422 }
423
424 #[test]
425 fn should_serialize_single_tuple_struct_as_newtype() {
426 #[derive(Reflect, Serialize, PartialEq, Debug)]
427 struct TupleStruct(u32);
428
429 #[derive(Reflect, Serialize, PartialEq, Debug)]
430 struct TupleStructWithSkip(
431 u32,
432 #[reflect(skip_serializing)]
433 #[serde(skip)]
434 u32,
435 );
436
437 #[derive(Reflect, Serialize, PartialEq, Debug)]
438 enum Enum {
439 TupleStruct(usize),
440 NestedTupleStruct(TupleStruct),
441 NestedTupleStructWithSkip(TupleStructWithSkip),
442 }
443
444 let mut registry = TypeRegistry::default();
445 registry.register::<TupleStruct>();
446 registry.register::<TupleStructWithSkip>();
447 registry.register::<Enum>();
448
449 let tuple_struct = TupleStruct(1);
450 let tuple_struct_with_skip = TupleStructWithSkip(2, 3);
451 let tuple_struct_enum = Enum::TupleStruct(4);
452 let nested_tuple_struct = Enum::NestedTupleStruct(TupleStruct(5));
453 let nested_tuple_struct_with_skip =
454 Enum::NestedTupleStructWithSkip(TupleStructWithSkip(6, 7));
455
456 fn assert_serialize<T: Reflect + FromReflect + Serialize + PartialEq + Debug>(
457 value: &T,
458 registry: &TypeRegistry,
459 ) {
460 let serializer = TypedReflectSerializer::new(value, registry);
461 let reflect_serialize = serde_json::to_string(&serializer).unwrap();
462 let serde_serialize = serde_json::to_string(value).unwrap();
463 assert_eq!(reflect_serialize, serde_serialize);
464
465 let registration = registry.get(TypeId::of::<T>()).unwrap();
466 let reflect_deserializer = TypedReflectDeserializer::new(registration, registry);
467
468 let mut deserializer = serde_json::Deserializer::from_str(&serde_serialize);
469 let reflect_value = reflect_deserializer.deserialize(&mut deserializer).unwrap();
470 let _ = T::from_reflect(&*reflect_value).unwrap();
471 }
472
473 assert_serialize(&tuple_struct, ®istry);
474 assert_serialize(&tuple_struct_with_skip, ®istry);
475 assert_serialize(&tuple_struct_enum, ®istry);
476 assert_serialize(&nested_tuple_struct, ®istry);
477 assert_serialize(&nested_tuple_struct_with_skip, ®istry);
478 }
479 }
480}