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