Skip to content

Commit 8e30d57

Browse files
committed
Add binary format support
1 parent 0eada70 commit 8e30d57

File tree

3 files changed

+270
-10
lines changed

3 files changed

+270
-10
lines changed

crates/bevy_reflect/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,4 @@ glam = { version = "0.21", features = ["serde"], optional = true }
3131

3232
[dev-dependencies]
3333
ron = "0.8.0"
34+
rmp-serde = "1.1"

crates/bevy_reflect/src/serde/de.rs

Lines changed: 215 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ trait TupleLikeInfo {
3535
fn get_field_len(&self) -> usize;
3636
}
3737

38+
trait Container {
39+
fn get_field_registration<'a, E: Error>(
40+
&self,
41+
index: usize,
42+
registry: &'a TypeRegistry,
43+
) -> Result<&'a TypeRegistration, E>;
44+
}
45+
3846
impl StructLikeInfo for StructInfo {
3947
fn get_name(&self) -> &str {
4048
self.type_name()
@@ -49,6 +57,23 @@ impl StructLikeInfo for StructInfo {
4957
}
5058
}
5159

60+
impl Container for StructInfo {
61+
fn get_field_registration<'a, E: Error>(
62+
&self,
63+
index: usize,
64+
registry: &'a TypeRegistry,
65+
) -> Result<&'a TypeRegistration, E> {
66+
let field = self.field_at(index).ok_or_else(|| {
67+
de::Error::custom(format_args!(
68+
"no field at index {} on struct {}",
69+
index,
70+
self.type_name(),
71+
))
72+
})?;
73+
get_registration(field.type_id(), field.type_name(), registry)
74+
}
75+
}
76+
5277
impl StructLikeInfo for StructVariantInfo {
5378
fn get_name(&self) -> &str {
5479
self.name()
@@ -63,6 +88,23 @@ impl StructLikeInfo for StructVariantInfo {
6388
}
6489
}
6590

91+
impl Container for StructVariantInfo {
92+
fn get_field_registration<'a, E: Error>(
93+
&self,
94+
index: usize,
95+
registry: &'a TypeRegistry,
96+
) -> Result<&'a TypeRegistration, E> {
97+
let field = self.field_at(index).ok_or_else(|| {
98+
de::Error::custom(format_args!(
99+
"no field at index {} on variant {}",
100+
index,
101+
self.name(),
102+
))
103+
})?;
104+
get_registration(field.type_id(), field.type_name(), registry)
105+
}
106+
}
107+
66108
impl TupleLikeInfo for TupleInfo {
67109
fn get_name(&self) -> &str {
68110
self.type_name()
@@ -151,6 +193,23 @@ impl<'de> Deserialize<'de> for Ident {
151193
}
152194
}
153195

196+
struct U32Visitor;
197+
198+
impl<'de> Visitor<'de> for U32Visitor {
199+
type Value = u32;
200+
201+
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
202+
formatter.write_str("u32")
203+
}
204+
205+
fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
206+
where
207+
E: Error,
208+
{
209+
Ok(v)
210+
}
211+
}
212+
154213
/// A general purpose deserializer for reflected types.
155214
///
156215
/// This will return a [`Box<dyn Reflect>`] containing the deserialized data.
@@ -192,7 +251,7 @@ impl<'a, 'de> DeserializeSeed<'de> for UntypedReflectDeserializer<'a> {
192251
where
193252
D: serde::Deserializer<'de>,
194253
{
195-
deserializer.deserialize_any(UntypedReflectDeserializerVisitor {
254+
deserializer.deserialize_map(UntypedReflectDeserializerVisitor {
196255
registry: self.registry,
197256
})
198257
}
@@ -396,6 +455,30 @@ impl<'a, 'de> Visitor<'de> for StructVisitor<'a> {
396455
{
397456
visit_struct(&mut map, self.struct_info, self.registry)
398457
}
458+
459+
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
460+
where
461+
A: SeqAccess<'de>,
462+
{
463+
let mut index = 0usize;
464+
let mut output = DynamicStruct::default();
465+
466+
while let Some(value) = seq.next_element_seed(TypedReflectDeserializer {
467+
registration: self
468+
.struct_info
469+
.get_field_registration(index, self.registry)?,
470+
registry: self.registry,
471+
})? {
472+
let name = self.struct_info.field_at(index).unwrap().name();
473+
output.insert_boxed(name, value);
474+
index += 1;
475+
if index >= self.struct_info.field_len() {
476+
break;
477+
}
478+
}
479+
480+
Ok(output)
481+
}
399482
}
400483

401484
struct TupleStructVisitor<'a> {
@@ -607,15 +690,10 @@ impl<'a, 'de> Visitor<'de> for EnumVisitor<'a> {
607690
A: EnumAccess<'de>,
608691
{
609692
let mut dynamic_enum = DynamicEnum::default();
610-
let (Ident(variant_name), variant) = data.variant().unwrap();
611-
let variant_info = self.enum_info.variant(&variant_name).ok_or_else(|| {
612-
let names = self.enum_info.iter().map(|variant| variant.name());
613-
Error::custom(format_args!(
614-
"unknown variant `{}`, expected one of {:?}",
615-
variant_name,
616-
ExpectedValues(names.collect())
617-
))
693+
let (variant_info, variant) = data.variant_seed(VariantDeserializer {
694+
enum_info: self.enum_info,
618695
})?;
696+
619697
let value: DynamicVariant = match variant_info {
620698
VariantInfo::Unit(..) => variant.unit_variant()?.into(),
621699
VariantInfo::Struct(struct_info) => variant
@@ -650,11 +728,63 @@ impl<'a, 'de> Visitor<'de> for EnumVisitor<'a> {
650728
.into(),
651729
};
652730

653-
dynamic_enum.set_variant(variant_name, value);
731+
dynamic_enum.set_variant(variant_info.name(), value);
654732
Ok(dynamic_enum)
655733
}
656734
}
657735

736+
struct VariantDeserializer {
737+
enum_info: &'static EnumInfo,
738+
}
739+
740+
impl<'de> DeserializeSeed<'de> for VariantDeserializer {
741+
type Value = &'static VariantInfo;
742+
743+
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
744+
where
745+
D: serde::Deserializer<'de>,
746+
{
747+
struct VariantVisitor(&'static EnumInfo);
748+
749+
impl<'de> Visitor<'de> for VariantVisitor {
750+
type Value = &'static VariantInfo;
751+
752+
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
753+
formatter.write_str("expected either a variant index or variant name")
754+
}
755+
756+
fn visit_str<E>(self, variant_name: &str) -> Result<Self::Value, E>
757+
where
758+
E: Error,
759+
{
760+
self.0.variant(variant_name).ok_or_else(|| {
761+
let names = self.0.iter().map(|variant| variant.name());
762+
Error::custom(format_args!(
763+
"unknown variant `{}`, expected one of {:?}",
764+
variant_name,
765+
ExpectedValues(names.collect())
766+
))
767+
})
768+
}
769+
770+
fn visit_u32<E>(self, variant_index: u32) -> Result<Self::Value, E>
771+
where
772+
E: Error,
773+
{
774+
self.0.variant_at(variant_index as usize).ok_or_else(|| {
775+
Error::custom(format_args!(
776+
"no variant found at index `{}` on enum `{}`",
777+
variant_index,
778+
self.0.name()
779+
))
780+
})
781+
}
782+
}
783+
784+
deserializer.deserialize_identifier(VariantVisitor(self.enum_info))
785+
}
786+
}
787+
658788
struct StructVariantVisitor<'a> {
659789
struct_info: &'static StructVariantInfo,
660790
registry: &'a TypeRegistry,
@@ -673,6 +803,30 @@ impl<'a, 'de> Visitor<'de> for StructVariantVisitor<'a> {
673803
{
674804
visit_struct(&mut map, self.struct_info, self.registry)
675805
}
806+
807+
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
808+
where
809+
A: SeqAccess<'de>,
810+
{
811+
let mut index = 0usize;
812+
let mut output = DynamicStruct::default();
813+
814+
while let Some(value) = seq.next_element_seed(TypedReflectDeserializer {
815+
registration: self
816+
.struct_info
817+
.get_field_registration(index, self.registry)?,
818+
registry: self.registry,
819+
})? {
820+
let name = self.struct_info.field_at(index).unwrap().name();
821+
output.insert_boxed(name, value);
822+
index += 1;
823+
if index >= self.struct_info.field_len() {
824+
break;
825+
}
826+
}
827+
828+
Ok(output)
829+
}
676830
}
677831

678832
struct TupleVariantVisitor<'a> {
@@ -1166,4 +1320,55 @@ mod tests {
11661320
});
11671321
assert!(expected.reflect_partial_eq(output.as_ref()).unwrap());
11681322
}
1323+
1324+
#[test]
1325+
fn should_deserialize_binary() {
1326+
let mut map = HashMap::new();
1327+
map.insert(64, 32);
1328+
1329+
let expected = MyStruct {
1330+
primitive_value: 123,
1331+
option_value: Some(String::from("Hello world!")),
1332+
option_value_complex: Some(SomeStruct { foo: 123 }),
1333+
tuple_value: (PI, 1337),
1334+
list_value: vec![-2, -1, 0, 1, 2],
1335+
array_value: [-2, -1, 0, 1, 2],
1336+
map_value: map,
1337+
struct_value: SomeStruct { foo: 999999999 },
1338+
tuple_struct_value: SomeTupleStruct(String::from("Tuple Struct")),
1339+
unit_enum: SomeEnum::Unit,
1340+
newtype_enum: SomeEnum::NewType(123),
1341+
tuple_enum: SomeEnum::Tuple(1.23, 3.21),
1342+
struct_enum: SomeEnum::Struct {
1343+
foo: String::from("Struct variant value"),
1344+
},
1345+
custom_deserialize: CustomDeserialize {
1346+
value: 100,
1347+
inner_struct: SomeDeserializableStruct { foo: 101 },
1348+
},
1349+
};
1350+
1351+
let input = vec![
1352+
129, 217, 40, 98, 101, 118, 121, 95, 114, 101, 102, 108, 101, 99, 116, 58, 58, 115,
1353+
101, 114, 100, 101, 58, 58, 100, 101, 58, 58, 116, 101, 115, 116, 115, 58, 58, 77, 121,
1354+
83, 116, 114, 117, 99, 116, 158, 123, 172, 72, 101, 108, 108, 111, 32, 119, 111, 114,
1355+
108, 100, 33, 145, 123, 146, 202, 64, 73, 15, 219, 205, 5, 57, 149, 254, 255, 0, 1, 2,
1356+
149, 254, 255, 0, 1, 2, 129, 64, 32, 145, 206, 59, 154, 201, 255, 145, 172, 84, 117,
1357+
112, 108, 101, 32, 83, 116, 114, 117, 99, 116, 164, 85, 110, 105, 116, 129, 167, 78,
1358+
101, 119, 84, 121, 112, 101, 123, 129, 165, 84, 117, 112, 108, 101, 146, 202, 63, 157,
1359+
112, 164, 202, 64, 77, 112, 164, 129, 166, 83, 116, 114, 117, 99, 116, 145, 180, 83,
1360+
116, 114, 117, 99, 116, 32, 118, 97, 114, 105, 97, 110, 116, 32, 118, 97, 108, 117,
1361+
101, 146, 100, 145, 101,
1362+
];
1363+
1364+
let registry = get_registry();
1365+
let deserializer = UntypedReflectDeserializer::new(&registry);
1366+
1367+
let dynamic_output = deserializer
1368+
.deserialize(&mut rmp_serde::Deserializer::new(input.as_slice()))
1369+
.unwrap();
1370+
1371+
let output = <MyStruct as FromReflect>::from_reflect(dynamic_output.as_ref()).unwrap();
1372+
assert_eq!(expected, output);
1373+
}
11691374
}

crates/bevy_reflect/src/serde/ser.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,7 @@ mod tests {
533533
registry.register::<SomeStruct>();
534534
registry.register::<SomeTupleStruct>();
535535
registry.register::<CustomSerialize>();
536+
registry.register::<SomeEnum>();
536537
registry.register::<SomeSerializableStruct>();
537538
registry.register_type_data::<SomeSerializableStruct, ReflectSerialize>();
538539
registry.register::<String>();
@@ -541,6 +542,59 @@ mod tests {
541542
registry
542543
}
543544

545+
#[test]
546+
fn should_serialize_binary() {
547+
let mut map = HashMap::new();
548+
map.insert(64, 32);
549+
550+
let input = MyStruct {
551+
primitive_value: 123,
552+
option_value: Some(String::from("Hello world!")),
553+
option_value_complex: Some(SomeStruct { foo: 123 }),
554+
tuple_value: (PI, 1337),
555+
list_value: vec![-2, -1, 0, 1, 2],
556+
array_value: [-2, -1, 0, 1, 2],
557+
map_value: map,
558+
struct_value: SomeStruct { foo: 999999999 },
559+
tuple_struct_value: SomeTupleStruct(String::from("Tuple Struct")),
560+
unit_enum: SomeEnum::Unit,
561+
newtype_enum: SomeEnum::NewType(123),
562+
tuple_enum: SomeEnum::Tuple(1.23, 3.21),
563+
struct_enum: SomeEnum::Struct {
564+
foo: String::from("Struct variant value"),
565+
},
566+
custom_serialize: CustomSerialize {
567+
value: 100,
568+
inner_struct: SomeSerializableStruct { foo: 101 },
569+
},
570+
};
571+
572+
let mut registry = get_registry();
573+
registry.register::<SomeStruct>();
574+
registry.register::<Option<SomeStruct>>();
575+
registry.register::<(f32, usize)>();
576+
registry.register::<Vec<i32>>();
577+
registry.register::<[i32; 5]>();
578+
registry.register::<HashMap<u8, usize>>();
579+
580+
let serializer = ReflectSerializer::new(&input, &registry);
581+
let bytes: Vec<u8> = rmp_serde::to_vec(&serializer).unwrap();
582+
583+
let expected: Vec<u8> = vec![
584+
129, 217, 41, 98, 101, 118, 121, 95, 114, 101, 102, 108, 101, 99, 116, 58, 58, 115,
585+
101, 114, 100, 101, 58, 58, 115, 101, 114, 58, 58, 116, 101, 115, 116, 115, 58, 58, 77,
586+
121, 83, 116, 114, 117, 99, 116, 158, 123, 172, 72, 101, 108, 108, 111, 32, 119, 111,
587+
114, 108, 100, 33, 145, 123, 146, 202, 64, 73, 15, 219, 205, 5, 57, 149, 254, 255, 0,
588+
1, 2, 149, 254, 255, 0, 1, 2, 129, 64, 32, 145, 206, 59, 154, 201, 255, 145, 172, 84,
589+
117, 112, 108, 101, 32, 83, 116, 114, 117, 99, 116, 164, 85, 110, 105, 116, 129, 167,
590+
78, 101, 119, 84, 121, 112, 101, 123, 129, 165, 84, 117, 112, 108, 101, 146, 202, 63,
591+
157, 112, 164, 202, 64, 77, 112, 164, 129, 166, 83, 116, 114, 117, 99, 116, 145, 180,
592+
83, 116, 114, 117, 99, 116, 32, 118, 97, 114, 105, 97, 110, 116, 32, 118, 97, 108, 117,
593+
101, 146, 100, 145, 101,
594+
];
595+
assert_eq!(expected, bytes);
596+
}
597+
544598
#[test]
545599
fn should_serialize() {
546600
let mut map = HashMap::new();

0 commit comments

Comments
 (0)