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 self as bevy_reflect, type_registry::TypeRegistry, DynamicStruct, DynamicTupleStruct,
14 FromReflect, 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 }.clone_dynamic();
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.clone_value();
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::sync::Arc;
193 use bevy_reflect_derive::reflect_trait;
194 use core::any::TypeId;
195 use core::fmt::{Debug, Formatter};
196 use serde::de::{SeqAccess, Visitor};
197 use serde::ser::SerializeSeq;
198 use serde::{Deserializer, Serialize, Serializer};
199
200 #[reflect_trait]
201 trait Enemy: Reflect + Debug {
202 #[allow(dead_code, reason = "this method is purely for testing purposes")]
203 fn hp(&self) -> u8;
204 }
205
206 impl TypePath for dyn Enemy {
208 fn type_path() -> &'static str {
209 "dyn bevy_reflect::serde::tests::type_data::Enemy"
210 }
211
212 fn short_type_path() -> &'static str {
213 "dyn Enemy"
214 }
215 }
216
217 #[derive(Reflect, Debug)]
218 #[reflect(Enemy)]
219 struct Skeleton(u8);
220
221 impl Enemy for Skeleton {
222 fn hp(&self) -> u8 {
223 self.0
224 }
225 }
226
227 #[derive(Reflect, Debug)]
228 #[reflect(Enemy)]
229 struct Zombie {
230 health: u8,
231 walk_speed: f32,
232 }
233
234 impl Enemy for Zombie {
235 fn hp(&self) -> u8 {
236 self.health
237 }
238 }
239
240 #[derive(Reflect, Debug)]
241 struct Level {
242 name: String,
243 enemies: EnemyList,
244 }
245
246 #[derive(Reflect, Debug)]
247 #[reflect(SerializeWithRegistry, DeserializeWithRegistry)]
248 struct EnemyList(Vec<Arc<dyn Enemy>>);
251
252 impl SerializeWithRegistry for EnemyList {
253 fn serialize<S>(
254 &self,
255 serializer: S,
256 registry: &TypeRegistry,
257 ) -> Result<S::Ok, S::Error>
258 where
259 S: Serializer,
260 {
261 let mut state = serializer.serialize_seq(Some(self.0.len()))?;
262 for enemy in &self.0 {
263 state.serialize_element(&ReflectSerializer::new(
264 (**enemy).as_partial_reflect(),
265 registry,
266 ))?;
267 }
268 state.end()
269 }
270 }
271
272 impl<'de> DeserializeWithRegistry<'de> for EnemyList {
273 fn deserialize<D>(deserializer: D, registry: &TypeRegistry) -> Result<Self, D::Error>
274 where
275 D: Deserializer<'de>,
276 {
277 struct EnemyListVisitor<'a> {
278 registry: &'a TypeRegistry,
279 }
280
281 impl<'a, 'de> Visitor<'de> for EnemyListVisitor<'a> {
282 type Value = Vec<Arc<dyn Enemy>>;
283
284 fn expecting(&self, formatter: &mut Formatter) -> core::fmt::Result {
285 write!(formatter, "a list of enemies")
286 }
287
288 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
289 where
290 A: SeqAccess<'de>,
291 {
292 let mut enemies = Vec::new();
293 while let Some(enemy) =
294 seq.next_element_seed(ReflectDeserializer::new(self.registry))?
295 {
296 let registration = self
297 .registry
298 .get_with_type_path(
299 enemy.get_represented_type_info().unwrap().type_path(),
300 )
301 .unwrap();
302
303 let enemy = registration
305 .data::<ReflectFromReflect>()
306 .unwrap()
307 .from_reflect(&*enemy)
308 .unwrap();
309
310 let enemy = registration
312 .data::<ReflectEnemy>()
313 .unwrap()
314 .get_boxed(enemy)
315 .unwrap();
316
317 enemies.push(enemy.into());
318 }
319
320 Ok(enemies)
321 }
322 }
323
324 deserializer
325 .deserialize_seq(EnemyListVisitor { registry })
326 .map(EnemyList)
327 }
328 }
329
330 fn create_registry() -> TypeRegistry {
331 let mut registry = TypeRegistry::default();
332 registry.register::<Level>();
333 registry.register::<EnemyList>();
334 registry.register::<Skeleton>();
335 registry.register::<Zombie>();
336 registry
337 }
338
339 #[test]
340 fn should_serialize_with_serialize_with_registry() {
341 let registry = create_registry();
342
343 let level = Level {
344 name: String::from("Level 1"),
345 enemies: EnemyList(vec![
346 Arc::new(Skeleton(10)),
347 Arc::new(Zombie {
348 health: 20,
349 walk_speed: 0.5,
350 }),
351 ]),
352 };
353
354 let serializer = ReflectSerializer::new(&level, ®istry);
355 let serialized = ron::ser::to_string(&serializer).unwrap();
356
357 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)}])}"#;
358
359 assert_eq!(expected, serialized);
360 }
361
362 #[test]
363 fn should_deserialize_with_deserialize_with_registry() {
364 let registry = create_registry();
365
366 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)}])}"#;
367
368 let mut deserializer = ron::de::Deserializer::from_str(input).unwrap();
369 let reflect_deserializer = ReflectDeserializer::new(®istry);
370 let value = reflect_deserializer.deserialize(&mut deserializer).unwrap();
371
372 let output = Level::from_reflect(&*value).unwrap();
373
374 let expected = Level {
375 name: String::from("Level 1"),
376 enemies: EnemyList(vec![
377 Arc::new(Skeleton(10)),
378 Arc::new(Zombie {
379 health: 20,
380 walk_speed: 0.5,
381 }),
382 ]),
383 };
384
385 assert_eq!(format!("{:?}", expected), format!("{:?}", output));
387
388 let unexpected = Level {
389 name: String::from("Level 1"),
390 enemies: EnemyList(vec![
391 Arc::new(Skeleton(20)),
392 Arc::new(Zombie {
393 health: 20,
394 walk_speed: 5.0,
395 }),
396 ]),
397 };
398
399 assert_ne!(format!("{:?}", unexpected), format!("{:?}", output));
401 }
402
403 #[test]
404 fn should_serialize_single_tuple_struct_as_newtype() {
405 #[derive(Reflect, Serialize, PartialEq, Debug)]
406 struct TupleStruct(u32);
407
408 #[derive(Reflect, Serialize, PartialEq, Debug)]
409 struct TupleStructWithSkip(
410 u32,
411 #[reflect(skip_serializing)]
412 #[serde(skip)]
413 u32,
414 );
415
416 #[derive(Reflect, Serialize, PartialEq, Debug)]
417 enum Enum {
418 TupleStruct(usize),
419 NestedTupleStruct(TupleStruct),
420 NestedTupleStructWithSkip(TupleStructWithSkip),
421 }
422
423 let mut registry = TypeRegistry::default();
424 registry.register::<TupleStruct>();
425 registry.register::<TupleStructWithSkip>();
426 registry.register::<Enum>();
427
428 let tuple_struct = TupleStruct(1);
429 let tuple_struct_with_skip = TupleStructWithSkip(2, 3);
430 let tuple_struct_enum = Enum::TupleStruct(4);
431 let nested_tuple_struct = Enum::NestedTupleStruct(TupleStruct(5));
432 let nested_tuple_struct_with_skip =
433 Enum::NestedTupleStructWithSkip(TupleStructWithSkip(6, 7));
434
435 fn assert_serialize<T: Reflect + FromReflect + Serialize + PartialEq + Debug>(
436 value: &T,
437 registry: &TypeRegistry,
438 ) {
439 let serializer = TypedReflectSerializer::new(value, registry);
440 let reflect_serialize = serde_json::to_string(&serializer).unwrap();
441 let serde_serialize = serde_json::to_string(value).unwrap();
442 assert_eq!(reflect_serialize, serde_serialize);
443
444 let registration = registry.get(TypeId::of::<T>()).unwrap();
445 let reflect_deserializer = TypedReflectDeserializer::new(registration, registry);
446
447 let mut deserializer = serde_json::Deserializer::from_str(&serde_serialize);
448 let reflect_value = reflect_deserializer.deserialize(&mut deserializer).unwrap();
449 let _ = T::from_reflect(&*reflect_value).unwrap();
450 }
451
452 assert_serialize(&tuple_struct, ®istry);
453 assert_serialize(&tuple_struct_with_skip, ®istry);
454 assert_serialize(&tuple_struct_enum, ®istry);
455 assert_serialize(&nested_tuple_struct, ®istry);
456 assert_serialize(&nested_tuple_struct_with_skip, ®istry);
457 }
458 }
459}