Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_reflect/src/serde/ser/mod.rs
6600 views
1
pub use processor::*;
2
pub use serializable::*;
3
pub use serialize_with_registry::*;
4
pub use serializer::*;
5
6
mod arrays;
7
mod custom_serialization;
8
mod enums;
9
mod error_utils;
10
mod lists;
11
mod maps;
12
mod processor;
13
mod serializable;
14
mod serialize_with_registry;
15
mod serializer;
16
mod sets;
17
mod structs;
18
mod tuple_structs;
19
mod tuples;
20
21
#[cfg(test)]
22
mod tests {
23
use crate::{
24
serde::{ReflectSerializer, ReflectSerializerProcessor},
25
PartialReflect, Reflect, ReflectSerialize, Struct, TypeRegistry,
26
};
27
#[cfg(feature = "functions")]
28
use alloc::boxed::Box;
29
use alloc::{
30
string::{String, ToString},
31
vec,
32
vec::Vec,
33
};
34
use bevy_platform::collections::{HashMap, HashSet};
35
use core::{any::TypeId, f32::consts::PI, ops::RangeInclusive};
36
use ron::{extensions::Extensions, ser::PrettyConfig};
37
use serde::{Serialize, Serializer};
38
39
#[derive(Reflect, Debug, PartialEq)]
40
struct MyStruct {
41
primitive_value: i8,
42
option_value: Option<String>,
43
option_value_complex: Option<SomeStruct>,
44
tuple_value: (f32, usize),
45
list_value: Vec<i32>,
46
array_value: [i32; 5],
47
map_value: HashMap<u8, usize>,
48
set_value: HashSet<u8>,
49
struct_value: SomeStruct,
50
tuple_struct_value: SomeTupleStruct,
51
unit_struct: SomeUnitStruct,
52
unit_enum: SomeEnum,
53
newtype_enum: SomeEnum,
54
tuple_enum: SomeEnum,
55
struct_enum: SomeEnum,
56
ignored_struct: SomeIgnoredStruct,
57
ignored_tuple_struct: SomeIgnoredTupleStruct,
58
ignored_struct_variant: SomeIgnoredEnum,
59
ignored_tuple_variant: SomeIgnoredEnum,
60
custom_serialize: CustomSerialize,
61
}
62
63
#[derive(Reflect, Debug, PartialEq)]
64
struct SomeStruct {
65
foo: i64,
66
}
67
68
#[derive(Reflect, Debug, PartialEq)]
69
struct SomeTupleStruct(String);
70
71
#[derive(Reflect, Debug, PartialEq)]
72
struct SomeUnitStruct;
73
74
#[derive(Reflect, Debug, PartialEq)]
75
struct SomeIgnoredStruct {
76
#[reflect(ignore)]
77
ignored: i32,
78
}
79
80
#[derive(Reflect, Debug, PartialEq)]
81
struct SomeIgnoredTupleStruct(#[reflect(ignore)] i32);
82
83
#[derive(Reflect, Debug, PartialEq)]
84
enum SomeEnum {
85
Unit,
86
NewType(usize),
87
Tuple(f32, f32),
88
Struct { foo: String },
89
}
90
91
#[derive(Reflect, Debug, PartialEq)]
92
enum SomeIgnoredEnum {
93
Tuple(#[reflect(ignore)] f32, #[reflect(ignore)] f32),
94
Struct {
95
#[reflect(ignore)]
96
foo: String,
97
},
98
}
99
100
#[derive(Reflect, Debug, PartialEq, Serialize)]
101
struct SomeSerializableStruct {
102
foo: i64,
103
}
104
105
/// Implements a custom serialize using `#[reflect(Serialize)]`.
106
///
107
/// For testing purposes, this just uses the generated one from deriving Serialize.
108
#[derive(Reflect, Debug, PartialEq, Serialize)]
109
#[reflect(Serialize)]
110
struct CustomSerialize {
111
value: usize,
112
#[serde(rename = "renamed")]
113
inner_struct: SomeSerializableStruct,
114
}
115
116
fn get_registry() -> TypeRegistry {
117
let mut registry = TypeRegistry::default();
118
registry.register::<MyStruct>();
119
registry.register::<SomeStruct>();
120
registry.register::<SomeTupleStruct>();
121
registry.register::<SomeUnitStruct>();
122
registry.register::<SomeIgnoredStruct>();
123
registry.register::<SomeIgnoredTupleStruct>();
124
registry.register::<SomeIgnoredEnum>();
125
registry.register::<CustomSerialize>();
126
registry.register::<SomeEnum>();
127
registry.register::<SomeSerializableStruct>();
128
registry.register_type_data::<SomeSerializableStruct, ReflectSerialize>();
129
registry.register::<String>();
130
registry.register::<Option<String>>();
131
registry.register_type_data::<Option<String>, ReflectSerialize>();
132
registry
133
}
134
135
fn get_my_struct() -> MyStruct {
136
let mut map = <HashMap<_, _>>::default();
137
map.insert(64, 32);
138
139
let mut set = <HashSet<_>>::default();
140
set.insert(64);
141
142
MyStruct {
143
primitive_value: 123,
144
option_value: Some(String::from("Hello world!")),
145
option_value_complex: Some(SomeStruct { foo: 123 }),
146
tuple_value: (PI, 1337),
147
list_value: vec![-2, -1, 0, 1, 2],
148
array_value: [-2, -1, 0, 1, 2],
149
map_value: map,
150
set_value: set,
151
struct_value: SomeStruct { foo: 999999999 },
152
tuple_struct_value: SomeTupleStruct(String::from("Tuple Struct")),
153
unit_struct: SomeUnitStruct,
154
unit_enum: SomeEnum::Unit,
155
newtype_enum: SomeEnum::NewType(123),
156
tuple_enum: SomeEnum::Tuple(1.23, 3.21),
157
struct_enum: SomeEnum::Struct {
158
foo: String::from("Struct variant value"),
159
},
160
ignored_struct: SomeIgnoredStruct { ignored: 123 },
161
ignored_tuple_struct: SomeIgnoredTupleStruct(123),
162
ignored_struct_variant: SomeIgnoredEnum::Struct {
163
foo: String::from("Struct Variant"),
164
},
165
ignored_tuple_variant: SomeIgnoredEnum::Tuple(1.23, 3.45),
166
custom_serialize: CustomSerialize {
167
value: 100,
168
inner_struct: SomeSerializableStruct { foo: 101 },
169
},
170
}
171
}
172
173
#[test]
174
fn should_serialize() {
175
let input = get_my_struct();
176
let registry = get_registry();
177
178
let serializer = ReflectSerializer::new(&input, &registry);
179
180
let config = PrettyConfig::default()
181
.new_line(String::from("\n"))
182
.indentor(String::from(" "));
183
184
let output = ron::ser::to_string_pretty(&serializer, config).unwrap();
185
let expected = r#"{
186
"bevy_reflect::serde::ser::tests::MyStruct": (
187
primitive_value: 123,
188
option_value: Some("Hello world!"),
189
option_value_complex: Some((
190
foo: 123,
191
)),
192
tuple_value: (3.1415927, 1337),
193
list_value: [
194
-2,
195
-1,
196
0,
197
1,
198
2,
199
],
200
array_value: (-2, -1, 0, 1, 2),
201
map_value: {
202
64: 32,
203
},
204
set_value: [
205
64,
206
],
207
struct_value: (
208
foo: 999999999,
209
),
210
tuple_struct_value: ("Tuple Struct"),
211
unit_struct: (),
212
unit_enum: Unit,
213
newtype_enum: NewType(123),
214
tuple_enum: Tuple(1.23, 3.21),
215
struct_enum: Struct(
216
foo: "Struct variant value",
217
),
218
ignored_struct: (),
219
ignored_tuple_struct: (),
220
ignored_struct_variant: Struct(),
221
ignored_tuple_variant: Tuple(),
222
custom_serialize: (
223
value: 100,
224
renamed: (
225
foo: 101,
226
),
227
),
228
),
229
}"#;
230
assert_eq!(expected, output);
231
}
232
233
#[test]
234
fn should_serialize_option() {
235
#[derive(Reflect, Debug, PartialEq)]
236
struct OptionTest {
237
none: Option<()>,
238
simple: Option<String>,
239
complex: Option<SomeStruct>,
240
}
241
242
let value = OptionTest {
243
none: None,
244
simple: Some(String::from("Hello world!")),
245
complex: Some(SomeStruct { foo: 123 }),
246
};
247
248
let registry = get_registry();
249
let serializer = ReflectSerializer::new(&value, &registry);
250
251
// === Normal === //
252
let config = PrettyConfig::default()
253
.new_line(String::from("\n"))
254
.indentor(String::from(" "));
255
256
let output = ron::ser::to_string_pretty(&serializer, config).unwrap();
257
let expected = r#"{
258
"bevy_reflect::serde::ser::tests::OptionTest": (
259
none: None,
260
simple: Some("Hello world!"),
261
complex: Some((
262
foo: 123,
263
)),
264
),
265
}"#;
266
267
assert_eq!(expected, output);
268
269
// === Implicit Some === //
270
let config = PrettyConfig::default()
271
.new_line(String::from("\n"))
272
.extensions(Extensions::IMPLICIT_SOME)
273
.indentor(String::from(" "));
274
275
let output = ron::ser::to_string_pretty(&serializer, config).unwrap();
276
let expected = r#"#![enable(implicit_some)]
277
{
278
"bevy_reflect::serde::ser::tests::OptionTest": (
279
none: None,
280
simple: "Hello world!",
281
complex: (
282
foo: 123,
283
),
284
),
285
}"#;
286
287
assert_eq!(expected, output);
288
}
289
290
#[test]
291
fn enum_should_serialize() {
292
#[derive(Reflect)]
293
enum MyEnum {
294
Unit,
295
NewType(usize),
296
Tuple(f32, f32),
297
Struct { value: String },
298
}
299
300
let mut registry = get_registry();
301
registry.register::<MyEnum>();
302
303
let config = PrettyConfig::default().new_line(String::from("\n"));
304
305
// === Unit Variant === //
306
let value = MyEnum::Unit;
307
let serializer = ReflectSerializer::new(&value, &registry);
308
let output = ron::ser::to_string_pretty(&serializer, config.clone()).unwrap();
309
let expected = r#"{
310
"bevy_reflect::serde::ser::tests::MyEnum": Unit,
311
}"#;
312
assert_eq!(expected, output);
313
314
// === NewType Variant === //
315
let value = MyEnum::NewType(123);
316
let serializer = ReflectSerializer::new(&value, &registry);
317
let output = ron::ser::to_string_pretty(&serializer, config.clone()).unwrap();
318
let expected = r#"{
319
"bevy_reflect::serde::ser::tests::MyEnum": NewType(123),
320
}"#;
321
assert_eq!(expected, output);
322
323
// === Tuple Variant === //
324
let value = MyEnum::Tuple(1.23, 3.21);
325
let serializer = ReflectSerializer::new(&value, &registry);
326
let output = ron::ser::to_string_pretty(&serializer, config.clone()).unwrap();
327
let expected = r#"{
328
"bevy_reflect::serde::ser::tests::MyEnum": Tuple(1.23, 3.21),
329
}"#;
330
assert_eq!(expected, output);
331
332
// === Struct Variant === //
333
let value = MyEnum::Struct {
334
value: String::from("I <3 Enums"),
335
};
336
let serializer = ReflectSerializer::new(&value, &registry);
337
let output = ron::ser::to_string_pretty(&serializer, config).unwrap();
338
let expected = r#"{
339
"bevy_reflect::serde::ser::tests::MyEnum": Struct(
340
value: "I <3 Enums",
341
),
342
}"#;
343
assert_eq!(expected, output);
344
}
345
346
#[test]
347
fn should_serialize_non_self_describing_binary() {
348
let input = get_my_struct();
349
let registry = get_registry();
350
351
let serializer = ReflectSerializer::new(&input, &registry);
352
let config = bincode::config::standard().with_fixed_int_encoding();
353
let bytes = bincode::serde::encode_to_vec(&serializer, config).unwrap();
354
355
let expected: Vec<u8> = vec![
356
1, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 98, 101, 118, 121, 95, 114, 101, 102,
357
108, 101, 99, 116, 58, 58, 115, 101, 114, 100, 101, 58, 58, 115, 101, 114, 58, 58, 116,
358
101, 115, 116, 115, 58, 58, 77, 121, 83, 116, 114, 117, 99, 116, 123, 1, 12, 0, 0, 0,
359
0, 0, 0, 0, 72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33, 1, 123, 0, 0, 0,
360
0, 0, 0, 0, 219, 15, 73, 64, 57, 5, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 254, 255,
361
255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 254, 255, 255, 255,
362
255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 32,
363
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 255, 201, 154, 59, 0, 0, 0, 0, 12, 0,
364
0, 0, 0, 0, 0, 0, 84, 117, 112, 108, 101, 32, 83, 116, 114, 117, 99, 116, 0, 0, 0, 0,
365
1, 0, 0, 0, 123, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 164, 112, 157, 63, 164, 112, 77, 64,
366
3, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 83, 116, 114, 117, 99, 116, 32, 118, 97, 114, 105,
367
97, 110, 116, 32, 118, 97, 108, 117, 101, 1, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0,
368
0, 0, 101, 0, 0, 0, 0, 0, 0, 0,
369
];
370
371
assert_eq!(expected, bytes);
372
}
373
374
#[test]
375
fn should_serialize_self_describing_binary() {
376
let input = get_my_struct();
377
let registry = get_registry();
378
379
let serializer = ReflectSerializer::new(&input, &registry);
380
let bytes: Vec<u8> = rmp_serde::to_vec(&serializer).unwrap();
381
382
let expected: Vec<u8> = vec![
383
129, 217, 41, 98, 101, 118, 121, 95, 114, 101, 102, 108, 101, 99, 116, 58, 58, 115,
384
101, 114, 100, 101, 58, 58, 115, 101, 114, 58, 58, 116, 101, 115, 116, 115, 58, 58, 77,
385
121, 83, 116, 114, 117, 99, 116, 220, 0, 20, 123, 172, 72, 101, 108, 108, 111, 32, 119,
386
111, 114, 108, 100, 33, 145, 123, 146, 202, 64, 73, 15, 219, 205, 5, 57, 149, 254, 255,
387
0, 1, 2, 149, 254, 255, 0, 1, 2, 129, 64, 32, 145, 64, 145, 206, 59, 154, 201, 255,
388
172, 84, 117, 112, 108, 101, 32, 83, 116, 114, 117, 99, 116, 144, 164, 85, 110, 105,
389
116, 129, 167, 78, 101, 119, 84, 121, 112, 101, 123, 129, 165, 84, 117, 112, 108, 101,
390
146, 202, 63, 157, 112, 164, 202, 64, 77, 112, 164, 129, 166, 83, 116, 114, 117, 99,
391
116, 145, 180, 83, 116, 114, 117, 99, 116, 32, 118, 97, 114, 105, 97, 110, 116, 32,
392
118, 97, 108, 117, 101, 144, 144, 129, 166, 83, 116, 114, 117, 99, 116, 144, 129, 165,
393
84, 117, 112, 108, 101, 144, 146, 100, 145, 101,
394
];
395
396
assert_eq!(expected, bytes);
397
}
398
399
#[test]
400
fn should_serialize_dynamic_option() {
401
#[derive(Default, Reflect)]
402
struct OtherStruct {
403
some: Option<SomeStruct>,
404
none: Option<SomeStruct>,
405
}
406
407
let value = OtherStruct {
408
some: Some(SomeStruct { foo: 999999999 }),
409
none: None,
410
};
411
let dynamic = value.to_dynamic_struct();
412
let reflect = dynamic.as_partial_reflect();
413
414
let registry = get_registry();
415
416
let serializer = ReflectSerializer::new(reflect, &registry);
417
418
let mut buf = Vec::new();
419
420
let format = serde_json::ser::PrettyFormatter::with_indent(b" ");
421
let mut ser = serde_json::Serializer::with_formatter(&mut buf, format);
422
423
serializer.serialize(&mut ser).unwrap();
424
425
let output = core::str::from_utf8(&buf).unwrap();
426
let expected = r#"{
427
"bevy_reflect::serde::ser::tests::OtherStruct": {
428
"some": {
429
"foo": 999999999
430
},
431
"none": null
432
}
433
}"#;
434
435
assert_eq!(expected, output);
436
}
437
438
#[test]
439
fn should_return_error_if_missing_registration() {
440
let value = RangeInclusive::<f32>::new(0.0, 1.0);
441
let registry = TypeRegistry::new();
442
443
let serializer = ReflectSerializer::new(&value, &registry);
444
let error = ron::ser::to_string(&serializer).unwrap_err();
445
#[cfg(feature = "debug_stack")]
446
assert_eq!(
447
error,
448
ron::Error::Message(
449
"type `core::ops::RangeInclusive<f32>` is not registered in the type registry (stack: `core::ops::RangeInclusive<f32>`)"
450
.to_string(),
451
)
452
);
453
#[cfg(not(feature = "debug_stack"))]
454
assert_eq!(
455
error,
456
ron::Error::Message(
457
"type `core::ops::RangeInclusive<f32>` is not registered in the type registry"
458
.to_string(),
459
)
460
);
461
}
462
463
#[test]
464
fn should_return_error_if_missing_type_data() {
465
let value = RangeInclusive::<f32>::new(0.0, 1.0);
466
let mut registry = TypeRegistry::new();
467
registry.register::<RangeInclusive<f32>>();
468
469
let serializer = ReflectSerializer::new(&value, &registry);
470
let error = ron::ser::to_string(&serializer).unwrap_err();
471
#[cfg(feature = "debug_stack")]
472
assert_eq!(
473
error,
474
ron::Error::Message(
475
"type `core::ops::RangeInclusive<f32>` did not register the `ReflectSerialize` or `ReflectSerializeWithRegistry` type data. For certain types, this may need to be registered manually using `register_type_data` (stack: `core::ops::RangeInclusive<f32>`)".to_string()
476
)
477
);
478
#[cfg(not(feature = "debug_stack"))]
479
assert_eq!(
480
error,
481
ron::Error::Message(
482
"type `core::ops::RangeInclusive<f32>` did not register the `ReflectSerialize` type data. For certain types, this may need to be registered manually using `register_type_data`".to_string()
483
)
484
);
485
}
486
487
#[test]
488
fn should_use_processor_for_custom_serialization() {
489
#[derive(Reflect, Debug, PartialEq)]
490
struct Foo {
491
bar: i32,
492
qux: i64,
493
}
494
495
struct FooProcessor;
496
497
impl ReflectSerializerProcessor for FooProcessor {
498
fn try_serialize<S>(
499
&self,
500
value: &dyn PartialReflect,
501
_: &TypeRegistry,
502
serializer: S,
503
) -> Result<Result<S::Ok, S>, S::Error>
504
where
505
S: Serializer,
506
{
507
let Some(value) = value.try_as_reflect() else {
508
return Ok(Err(serializer));
509
};
510
511
let type_id = value.reflect_type_info().type_id();
512
if type_id == TypeId::of::<i64>() {
513
Ok(Ok(serializer.serialize_str("custom!")?))
514
} else {
515
Ok(Err(serializer))
516
}
517
}
518
}
519
520
let value = Foo { bar: 123, qux: 456 };
521
522
let mut registry = TypeRegistry::new();
523
registry.register::<Foo>();
524
525
let processor = FooProcessor;
526
let serializer = ReflectSerializer::with_processor(&value, &registry, &processor);
527
528
let config = PrettyConfig::default().new_line(String::from("\n"));
529
let output = ron::ser::to_string_pretty(&serializer, config).unwrap();
530
531
let expected = r#"{
532
"bevy_reflect::serde::ser::tests::Foo": (
533
bar: 123,
534
qux: "custom!",
535
),
536
}"#;
537
538
assert_eq!(expected, output);
539
}
540
541
#[test]
542
fn should_use_processor_for_multiple_registrations() {
543
#[derive(Reflect, Debug, PartialEq)]
544
struct Foo {
545
bar: i32,
546
sub: SubFoo,
547
}
548
549
#[derive(Reflect, Debug, PartialEq)]
550
struct SubFoo {
551
val: i32,
552
}
553
554
struct FooProcessor;
555
556
impl ReflectSerializerProcessor for FooProcessor {
557
fn try_serialize<S>(
558
&self,
559
value: &dyn PartialReflect,
560
_: &TypeRegistry,
561
serializer: S,
562
) -> Result<Result<S::Ok, S>, S::Error>
563
where
564
S: Serializer,
565
{
566
let Some(value) = value.try_as_reflect() else {
567
return Ok(Err(serializer));
568
};
569
570
let type_id = value.reflect_type_info().type_id();
571
if type_id == TypeId::of::<i32>() {
572
Ok(Ok(serializer.serialize_str("an i32")?))
573
} else if type_id == TypeId::of::<SubFoo>() {
574
Ok(Ok(serializer.serialize_str("a SubFoo")?))
575
} else {
576
Ok(Err(serializer))
577
}
578
}
579
}
580
581
let value = Foo {
582
bar: 123,
583
sub: SubFoo { val: 456 },
584
};
585
586
let mut registry = TypeRegistry::new();
587
registry.register::<Foo>();
588
registry.register::<SubFoo>();
589
590
let processor = FooProcessor;
591
let serializer = ReflectSerializer::with_processor(&value, &registry, &processor);
592
593
let config = PrettyConfig::default().new_line(String::from("\n"));
594
let output = ron::ser::to_string_pretty(&serializer, config).unwrap();
595
596
let expected = r#"{
597
"bevy_reflect::serde::ser::tests::Foo": (
598
bar: "an i32",
599
sub: "a SubFoo",
600
),
601
}"#;
602
603
assert_eq!(expected, output);
604
}
605
606
#[test]
607
fn should_propagate_processor_serialize_error() {
608
struct ErroringProcessor;
609
610
impl ReflectSerializerProcessor for ErroringProcessor {
611
fn try_serialize<S>(
612
&self,
613
value: &dyn PartialReflect,
614
_: &TypeRegistry,
615
serializer: S,
616
) -> Result<Result<S::Ok, S>, S::Error>
617
where
618
S: Serializer,
619
{
620
let Some(value) = value.try_as_reflect() else {
621
return Ok(Err(serializer));
622
};
623
624
let type_id = value.reflect_type_info().type_id();
625
if type_id == TypeId::of::<i32>() {
626
Err(serde::ser::Error::custom("my custom serialize error"))
627
} else {
628
Ok(Err(serializer))
629
}
630
}
631
}
632
633
let value = 123_i32;
634
635
let registry = TypeRegistry::new();
636
637
let processor = ErroringProcessor;
638
let serializer = ReflectSerializer::with_processor(&value, &registry, &processor);
639
let error = ron::ser::to_string_pretty(&serializer, PrettyConfig::default()).unwrap_err();
640
641
#[cfg(feature = "debug_stack")]
642
assert_eq!(
643
error,
644
ron::Error::Message("my custom serialize error (stack: `i32`)".to_string())
645
);
646
#[cfg(not(feature = "debug_stack"))]
647
assert_eq!(
648
error,
649
ron::Error::Message("my custom serialize error".to_string())
650
);
651
}
652
653
#[cfg(feature = "functions")]
654
mod functions {
655
use super::*;
656
use crate::func::{DynamicFunction, IntoFunction};
657
use alloc::string::ToString;
658
659
#[test]
660
fn should_not_serialize_function() {
661
#[derive(Reflect)]
662
#[reflect(from_reflect = false)]
663
struct MyStruct {
664
func: DynamicFunction<'static>,
665
}
666
667
let value: Box<dyn Reflect> = Box::new(MyStruct {
668
func: String::new.into_function(),
669
});
670
671
let registry = TypeRegistry::new();
672
let serializer = ReflectSerializer::new(value.as_partial_reflect(), &registry);
673
674
let error = ron::ser::to_string(&serializer).unwrap_err();
675
676
#[cfg(feature = "debug_stack")]
677
assert_eq!(
678
error,
679
ron::Error::Message("functions cannot be serialized (stack: `bevy_reflect::serde::ser::tests::functions::MyStruct`)".to_string())
680
);
681
682
#[cfg(not(feature = "debug_stack"))]
683
assert_eq!(
684
error,
685
ron::Error::Message("functions cannot be serialized".to_string())
686
);
687
}
688
}
689
690
#[cfg(feature = "debug_stack")]
691
mod debug_stack {
692
use super::*;
693
694
#[test]
695
fn should_report_context_in_errors() {
696
#[derive(Reflect)]
697
struct Foo {
698
bar: Bar,
699
}
700
701
#[derive(Reflect)]
702
struct Bar {
703
some_other_field: Option<u32>,
704
baz: Baz,
705
}
706
707
#[derive(Reflect)]
708
struct Baz {
709
value: Vec<RangeInclusive<f32>>,
710
}
711
712
let value = Foo {
713
bar: Bar {
714
some_other_field: Some(123),
715
baz: Baz {
716
value: vec![0.0..=1.0],
717
},
718
},
719
};
720
721
let registry = TypeRegistry::new();
722
let serializer = ReflectSerializer::new(&value, &registry);
723
724
let error = ron::ser::to_string(&serializer).unwrap_err();
725
assert_eq!(
726
error,
727
ron::Error::Message(
728
"type `core::ops::RangeInclusive<f32>` is not registered in the type registry (stack: `bevy_reflect::serde::ser::tests::debug_stack::Foo` -> `bevy_reflect::serde::ser::tests::debug_stack::Bar` -> `bevy_reflect::serde::ser::tests::debug_stack::Baz` -> `alloc::vec::Vec<core::ops::RangeInclusive<f32>>` -> `core::ops::RangeInclusive<f32>`)".to_string()
729
)
730
);
731
}
732
}
733
}
734
735