Skip to content

Commit c81cbb1

Browse files
committed
wip: ser tests
1 parent 914b518 commit c81cbb1

File tree

2 files changed

+124
-5
lines changed

2 files changed

+124
-5
lines changed

crates/bevy_reflect/src/serde/ser/mod.rs

Lines changed: 118 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@ mod tuples;
1616
#[cfg(test)]
1717
mod tests {
1818
use crate::{
19-
self as bevy_reflect, serde::ReflectSerializer, PartialReflect, Reflect, ReflectSerialize,
20-
Struct, TypeRegistry,
19+
self as bevy_reflect,
20+
serde::{ReflectSerializer, ReflectSerializerProcessor},
21+
PartialReflect, Reflect, ReflectSerialize, Struct, TypeRegistry,
2122
};
2223
use bevy_utils::{HashMap, HashSet};
2324
use core::{f32::consts::PI, ops::RangeInclusive};
2425
use ron::{extensions::Extensions, ser::PrettyConfig};
25-
use serde::Serialize;
26+
use serde::{Serialize, Serializer};
27+
use std::any::TypeId;
2628

2729
#[derive(Reflect, Debug, PartialEq)]
2830
struct MyStruct {
@@ -471,6 +473,119 @@ mod tests {
471473
);
472474
}
473475

476+
#[test]
477+
fn should_use_processor_for_custom_serialization() {
478+
#[derive(Reflect, Debug, PartialEq)]
479+
struct Foo {
480+
bar: i32,
481+
qux: i64,
482+
}
483+
484+
struct FooProcessor;
485+
486+
impl ReflectSerializerProcessor for FooProcessor {
487+
fn try_serialize<S>(
488+
&self,
489+
value: &dyn PartialReflect,
490+
_: &TypeRegistry,
491+
serializer: S,
492+
) -> Result<Result<S::Ok, S>, S::Error>
493+
where
494+
S: Serializer,
495+
{
496+
let Some(value) = value.try_as_reflect() else {
497+
return Ok(Err(serializer));
498+
};
499+
500+
let type_id = value.reflect_type_info().type_id();
501+
if type_id == TypeId::of::<i64>() {
502+
serializer.serialize_str("custom!").map(Ok)
503+
} else {
504+
Ok(Err(serializer))
505+
}
506+
}
507+
}
508+
509+
let value = Foo { bar: 123, qux: 456 };
510+
511+
let mut registry = TypeRegistry::new();
512+
registry.register::<Foo>();
513+
514+
let mut processor = FooProcessor;
515+
let serializer = ReflectSerializer::with_processor(&value, &registry, &mut processor);
516+
let output = ron::ser::to_string_pretty(&serializer, PrettyConfig::default()).unwrap();
517+
let expected = r#"{
518+
"bevy_reflect::serde::ser::tests::Foo": (
519+
bar: 123,
520+
qux: "custom!",
521+
),
522+
}"#;
523+
524+
assert_eq!(expected, output);
525+
}
526+
527+
#[test]
528+
fn should_use_processor_for_multiple_registrations() {
529+
#[derive(Reflect, Debug, PartialEq)]
530+
struct Foo {
531+
bar: i32,
532+
sub: SubFoo,
533+
}
534+
535+
#[derive(Reflect, Debug, PartialEq)]
536+
struct SubFoo {
537+
val: i32,
538+
}
539+
540+
struct FooProcessor;
541+
542+
impl ReflectSerializerProcessor for FooProcessor {
543+
fn try_serialize<S>(
544+
&self,
545+
value: &dyn PartialReflect,
546+
_: &TypeRegistry,
547+
serializer: S,
548+
) -> Result<Result<S::Ok, S>, S::Error>
549+
where
550+
S: Serializer,
551+
{
552+
let Some(value) = value.try_as_reflect() else {
553+
return Ok(Err(serializer));
554+
};
555+
556+
let type_id = value.reflect_type_info().type_id();
557+
if type_id == TypeId::of::<i32>() {
558+
serializer.serialize_str("an i32").map(Ok)
559+
} else if type_id == TypeId::of::<SubFoo>() {
560+
serializer.serialize_str("a SubFoo").map(Ok)
561+
} else {
562+
Ok(Err(serializer))
563+
}
564+
}
565+
}
566+
567+
let value = Foo {
568+
bar: 123,
569+
sub: SubFoo { val: 456 },
570+
};
571+
572+
let mut registry = TypeRegistry::new();
573+
registry.register::<Foo>();
574+
registry.register::<SubFoo>();
575+
576+
let mut processor = FooProcessor;
577+
let serializer = ReflectSerializer::with_processor(&value, &registry, &mut processor);
578+
let output = ron::ser::to_string_pretty(&serializer, PrettyConfig::default()).unwrap();
579+
let expected = r#"{
580+
"bevy_reflect::serde::ser::tests::Foo": (
581+
bar: "an i32",
582+
sub: "a SubFoo",
583+
),
584+
}"#;
585+
586+
assert_eq!(expected, output);
587+
}
588+
474589
#[cfg(feature = "functions")]
475590
mod functions {
476591
use super::*;

crates/bevy_reflect/src/serde/ser/serializer.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub trait ReflectSerializerProcessor {
1818
fn try_serialize<S>(
1919
&self,
2020
value: &dyn PartialReflect,
21+
registry: &TypeRegistry,
2122
serializer: S,
2223
) -> Result<Result<S::Ok, S>, S::Error>
2324
where
@@ -28,6 +29,7 @@ impl ReflectSerializerProcessor for () {
2829
fn try_serialize<S>(
2930
&self,
3031
_value: &dyn PartialReflect,
32+
_registry: &TypeRegistry,
3133
serializer: S,
3234
) -> Result<Result<S::Ok, S>, S::Error>
3335
where
@@ -126,7 +128,7 @@ impl<P: ReflectSerializerProcessor> Serialize for ReflectSerializer<'_, P> {
126128
}
127129
})?
128130
.type_path(),
129-
&TypedReflectSerializer::with_processor(self.value, self.registry, self.processor),
131+
&TypedReflectSerializer::new_internal(self.value, self.registry, self.processor),
130132
)?;
131133
state.end()
132134
}
@@ -231,8 +233,10 @@ impl<P: ReflectSerializerProcessor> Serialize for TypedReflectSerializer<'_, P>
231233
}
232234
}
233235

236+
// First, check if our processor wants to serialize this type
237+
// This takes priority over any other serialization operations
234238
let serializer = if let Some(processor) = self.processor.as_deref() {
235-
match processor.try_serialize(self.value, serializer) {
239+
match processor.try_serialize(self.value, self.registry, serializer) {
236240
Ok(Ok(value)) => {
237241
return Ok(value);
238242
}

0 commit comments

Comments
 (0)