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