Skip to content

Commit 5e74561

Browse files
authored
Implement Reflect for tuples up to length 12 (#1218)
Add Reflect impls for tuples up to length 12
1 parent 9bce871 commit 5e74561

File tree

7 files changed

+435
-6
lines changed

7 files changed

+435
-6
lines changed

crates/bevy_reflect/src/lib.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ mod map;
33
mod path;
44
mod reflect;
55
mod struct_trait;
6+
mod tuple;
67
mod tuple_struct;
78
mod type_registry;
89
mod type_uuid;
@@ -46,6 +47,7 @@ pub use map::*;
4647
pub use path::*;
4748
pub use reflect::*;
4849
pub use struct_trait::*;
50+
pub use tuple::*;
4951
pub use tuple_struct::*;
5052
pub use type_registry::*;
5153
pub use type_uuid::*;
@@ -208,6 +210,7 @@ mod tests {
208210
c: Vec<isize>,
209211
d: HashMap<usize, i8>,
210212
e: Bar,
213+
f: (i32, Vec<isize>, Bar),
211214
}
212215

213216
#[derive(Reflect, Eq, PartialEq, Debug)]
@@ -224,6 +227,7 @@ mod tests {
224227
c: vec![1, 2],
225228
d: hash_map,
226229
e: Bar { x: 1 },
230+
f: (1, vec![1, 2], Bar { x: 1 }),
227231
};
228232

229233
let mut foo_patch = DynamicStruct::default();
@@ -234,15 +238,21 @@ mod tests {
234238
list.push(3isize);
235239
list.push(4isize);
236240
list.push(5isize);
237-
foo_patch.insert("c", list);
241+
foo_patch.insert("c", list.clone_dynamic());
238242

239243
let mut map = DynamicMap::default();
240244
map.insert(2usize, 3i8);
241245
foo_patch.insert("d", map);
242246

243247
let mut bar_patch = DynamicStruct::default();
244248
bar_patch.insert("x", 2u32);
245-
foo_patch.insert("e", bar_patch);
249+
foo_patch.insert("e", bar_patch.clone_dynamic());
250+
251+
let mut tuple = DynamicTuple::default();
252+
tuple.insert(2i32);
253+
tuple.insert(list);
254+
tuple.insert(bar_patch);
255+
foo_patch.insert("f", tuple);
246256

247257
foo.apply(&foo_patch);
248258

@@ -255,6 +265,7 @@ mod tests {
255265
c: vec![3, 4, 5],
256266
d: hash_map,
257267
e: Bar { x: 2 },
268+
f: (2, vec![3, 4, 5], Bar { x: 2 }),
258269
};
259270

260271
assert_eq!(foo, expected_foo);
@@ -271,6 +282,7 @@ mod tests {
271282
d: HashMap<usize, i8>,
272283
e: Bar,
273284
f: String,
285+
g: (i32, Vec<isize>, Bar),
274286
}
275287

276288
#[derive(Reflect)]
@@ -288,6 +300,7 @@ mod tests {
288300
d: hash_map,
289301
e: Bar { x: 1 },
290302
f: "hi".to_string(),
303+
g: (1, vec![1, 2], Bar { x: 1 }),
291304
};
292305

293306
let mut registry = TypeRegistry::default();
@@ -297,6 +310,7 @@ mod tests {
297310
registry.register::<Bar>();
298311
registry.register::<String>();
299312
registry.register::<i8>();
313+
registry.register::<i32>();
300314

301315
let serializer = ReflectSerializer::new(&foo, &registry);
302316
let serialized = to_string_pretty(&serializer, PrettyConfig::default()).unwrap();

crates/bevy_reflect/src/reflect.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
use crate::{serde::Serializable, List, Map, Struct, TupleStruct};
1+
use crate::{serde::Serializable, List, Map, Struct, Tuple, TupleStruct};
22
use std::{any::Any, fmt::Debug};
33

44
pub use bevy_utils::AHasher as ReflectHasher;
55

66
pub enum ReflectRef<'a> {
77
Struct(&'a dyn Struct),
88
TupleStruct(&'a dyn TupleStruct),
9+
Tuple(&'a dyn Tuple),
910
List(&'a dyn List),
1011
Map(&'a dyn Map),
1112
Value(&'a dyn Reflect),
@@ -14,6 +15,7 @@ pub enum ReflectRef<'a> {
1415
pub enum ReflectMut<'a> {
1516
Struct(&'a mut dyn Struct),
1617
TupleStruct(&'a mut dyn TupleStruct),
18+
Tuple(&'a dyn Tuple),
1719
List(&'a mut dyn List),
1820
Map(&'a mut dyn Map),
1921
Value(&'a mut dyn Reflect),

crates/bevy_reflect/src/serde/de.rs

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::{
2-
serde::type_fields, DynamicList, DynamicMap, DynamicStruct, DynamicTupleStruct, Reflect,
3-
ReflectDeserialize, TypeRegistry,
2+
serde::type_fields, DynamicList, DynamicMap, DynamicStruct, DynamicTuple, DynamicTupleStruct,
3+
Reflect, ReflectDeserialize, TypeRegistry,
44
};
55
use erased_serde::Deserializer;
66
use serde::de::{self, DeserializeSeed, MapAccess, SeqAccess, Visitor};
@@ -176,6 +176,15 @@ impl<'a, 'de> Visitor<'de> for ReflectVisitor<'a> {
176176
tuple_struct.set_name(type_name);
177177
return Ok(Box::new(tuple_struct));
178178
}
179+
type_fields::TUPLE => {
180+
let _type_name = type_name
181+
.take()
182+
.ok_or_else(|| de::Error::missing_field(type_fields::TYPE))?;
183+
let tuple = map.next_value_seed(TupleDeserializer {
184+
registry: self.registry,
185+
})?;
186+
return Ok(Box::new(tuple));
187+
}
179188
type_fields::LIST => {
180189
let _type_name = type_name
181190
.take()
@@ -401,3 +410,45 @@ impl<'a, 'de> Visitor<'de> for TupleStructVisitor<'a> {
401410
Ok(tuple_struct)
402411
}
403412
}
413+
414+
struct TupleDeserializer<'a> {
415+
registry: &'a TypeRegistry,
416+
}
417+
418+
impl<'a, 'de> DeserializeSeed<'de> for TupleDeserializer<'a> {
419+
type Value = DynamicTuple;
420+
421+
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
422+
where
423+
D: serde::Deserializer<'de>,
424+
{
425+
deserializer.deserialize_seq(TupleVisitor {
426+
registry: self.registry,
427+
})
428+
}
429+
}
430+
431+
struct TupleVisitor<'a> {
432+
registry: &'a TypeRegistry,
433+
}
434+
435+
impl<'a, 'de> Visitor<'de> for TupleVisitor<'a> {
436+
type Value = DynamicTuple;
437+
438+
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
439+
formatter.write_str("tuple value")
440+
}
441+
442+
fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
443+
where
444+
V: SeqAccess<'de>,
445+
{
446+
let mut tuple = DynamicTuple::default();
447+
while let Some(value) = seq.next_element_seed(ReflectDeserializer {
448+
registry: self.registry,
449+
})? {
450+
tuple.insert_boxed(value);
451+
}
452+
Ok(tuple)
453+
}
454+
}

crates/bevy_reflect/src/serde/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub(crate) mod type_fields {
99
pub const MAP: &str = "map";
1010
pub const STRUCT: &str = "struct";
1111
pub const TUPLE_STRUCT: &str = "tuple_struct";
12+
pub const TUPLE: &str = "tuple";
1213
pub const LIST: &str = "list";
1314
pub const VALUE: &str = "value";
1415
}

crates/bevy_reflect/src/serde/ser.rs

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::{
2-
serde::type_fields, List, Map, Reflect, ReflectRef, Struct, TupleStruct, TypeRegistry,
2+
serde::type_fields, List, Map, Reflect, ReflectRef, Struct, Tuple, TupleStruct, TypeRegistry,
33
};
44
use serde::{
55
ser::{SerializeMap, SerializeSeq},
@@ -57,6 +57,11 @@ impl<'a> Serialize for ReflectSerializer<'a> {
5757
registry: self.registry,
5858
}
5959
.serialize(serializer),
60+
ReflectRef::Tuple(value) => TupleSerializer {
61+
tuple: value,
62+
registry: self.registry,
63+
}
64+
.serialize(serializer),
6065
ReflectRef::List(value) => ListSerializer {
6166
list: value,
6267
registry: self.registry,
@@ -181,6 +186,48 @@ impl<'a> Serialize for TupleStructValueSerializer<'a> {
181186
}
182187
}
183188

189+
pub struct TupleSerializer<'a> {
190+
pub tuple: &'a dyn Tuple,
191+
pub registry: &'a TypeRegistry,
192+
}
193+
194+
impl<'a> Serialize for TupleSerializer<'a> {
195+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
196+
where
197+
S: serde::Serializer,
198+
{
199+
let mut state = serializer.serialize_map(Some(2))?;
200+
201+
state.serialize_entry(type_fields::TYPE, self.tuple.type_name())?;
202+
state.serialize_entry(
203+
type_fields::TUPLE,
204+
&TupleValueSerializer {
205+
tuple: self.tuple,
206+
registry: self.registry,
207+
},
208+
)?;
209+
state.end()
210+
}
211+
}
212+
213+
pub struct TupleValueSerializer<'a> {
214+
pub tuple: &'a dyn Tuple,
215+
pub registry: &'a TypeRegistry,
216+
}
217+
218+
impl<'a> Serialize for TupleValueSerializer<'a> {
219+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
220+
where
221+
S: serde::Serializer,
222+
{
223+
let mut state = serializer.serialize_seq(Some(self.tuple.field_len()))?;
224+
for value in self.tuple.iter_fields() {
225+
state.serialize_element(&ReflectSerializer::new(value, self.registry))?;
226+
}
227+
state.end()
228+
}
229+
}
230+
184231
pub struct MapSerializer<'a> {
185232
pub map: &'a dyn Map,
186233
pub registry: &'a TypeRegistry,

0 commit comments

Comments
 (0)