1use core::{cell::RefCell, fmt};
13
14use serde::{
15 de::{DeserializeSeed, MapAccess, Visitor},
16 ser::SerializeMap,
17 Deserializer, Serialize, Serializer,
18};
19
20use crate::{Component, EntityBuilder, EntityRef, Query, World};
21
22pub trait SerializeContext {
61 fn serialize_entity<S>(&mut self, entity: EntityRef<'_>, map: S) -> Result<S::Ok, S::Error>
63 where
64 S: SerializeMap;
65
66 fn component_count(&self, entity: EntityRef<'_>) -> Option<usize> {
72 let _ = entity;
73 None
74 }
75}
76
77pub fn try_serialize<T: Component + Serialize, K: Serialize + ?Sized, S: SerializeMap>(
81 entity: &EntityRef<'_>,
82 key: &K,
83 map: &mut S,
84) -> Result<(), S::Error> {
85 if let Some(x) = entity.get::<&T>() {
86 map.serialize_key(key)?;
87 map.serialize_value(&*x)?;
88 }
89 Ok(())
90}
91
92pub fn serialize<C, S>(world: &World, context: &mut C, serializer: S) -> Result<S::Ok, S::Error>
96where
97 C: SerializeContext,
98 S: Serializer,
99{
100 let mut seq = serializer.serialize_map(Some(world.len() as usize))?;
101 for entity in world {
102 seq.serialize_key(&entity.entity())?;
103 seq.serialize_value(&SerializeComponents(RefCell::new((context, Some(entity)))))?;
104 }
105 seq.end()
106}
107
108pub fn serialize_satisfying<Q: Query, C, S>(
110 world: &World,
111 context: &mut C,
112 serializer: S,
113) -> Result<S::Ok, S::Error>
114where
115 C: SerializeContext,
116 S: Serializer,
117{
118 let entity_count = world
119 .archetypes()
120 .filter(|a| a.satisfies::<Q>())
121 .map(|a| a.len() as usize)
122 .sum();
123 let mut seq = serializer.serialize_map(Some(entity_count))?;
124 for entity in world {
125 if entity.satisfies::<Q>() {
126 seq.serialize_key(&entity.entity())?;
127 seq.serialize_value(&SerializeComponents(RefCell::new((context, Some(entity)))))?;
128 }
129 }
130 seq.end()
131}
132
133struct SerializeComponents<'a, C>(RefCell<(&'a mut C, Option<EntityRef<'a>>)>);
134
135impl<C: SerializeContext> Serialize for SerializeComponents<'_, C> {
136 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
137 where
138 S: serde::Serializer,
139 {
140 let mut this = self.0.borrow_mut();
141 let entity = this.1.take().unwrap();
142 let map = serializer.serialize_map(this.0.component_count(entity))?;
143 this.0.serialize_entity(entity, map)
144 }
145}
146
147pub fn deserialize<'de, C, D>(context: &mut C, deserializer: D) -> Result<World, D::Error>
149where
150 C: DeserializeContext,
151 D: Deserializer<'de>,
152{
153 deserializer.deserialize_map(WorldVisitor(context))
154}
155
156pub trait DeserializeContext {
200 fn deserialize_entity<'de, M>(
202 &mut self,
203 map: M,
204 entity: &mut EntityBuilder,
205 ) -> Result<(), M::Error>
206 where
207 M: MapAccess<'de>;
208}
209
210struct WorldVisitor<'a, C>(&'a mut C);
211
212impl<'de, C> Visitor<'de> for WorldVisitor<'_, C>
213where
214 C: DeserializeContext,
215{
216 type Value = World;
217
218 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
219 formatter.write_str("a world")
220 }
221
222 fn visit_map<A>(self, mut map: A) -> Result<World, A::Error>
223 where
224 A: MapAccess<'de>,
225 {
226 let mut world = World::new();
227 let mut builder = EntityBuilder::new();
228 while let Some(id) = map.next_key()? {
229 map.next_value_seed(DeserializeComponents(self.0, &mut builder))?;
230 world.spawn_at(id, builder.build());
231 }
232 Ok(world)
233 }
234}
235
236struct DeserializeComponents<'a, C>(&'a mut C, &'a mut EntityBuilder);
237
238impl<'de, C> DeserializeSeed<'de> for DeserializeComponents<'_, C>
239where
240 C: DeserializeContext,
241{
242 type Value = ();
243
244 fn deserialize<D>(self, deserializer: D) -> Result<(), D::Error>
245 where
246 D: Deserializer<'de>,
247 {
248 deserializer.deserialize_map(ComponentsVisitor(self.0, self.1))
249 }
250}
251
252struct ComponentsVisitor<'a, C>(&'a mut C, &'a mut EntityBuilder);
253
254impl<'de, C> Visitor<'de> for ComponentsVisitor<'_, C>
255where
256 C: DeserializeContext,
257{
258 type Value = ();
259
260 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
261 formatter.write_str("an entity's components")
262 }
263
264 fn visit_map<A>(self, map: A) -> Result<(), A::Error>
265 where
266 A: MapAccess<'de>,
267 {
268 self.0.deserialize_entity(map, self.1)
269 }
270}
271
272#[cfg(test)]
273mod tests {
274 use core::marker::PhantomData;
275 use std::fmt;
276
277 use serde::{Deserialize, Serialize};
278
279 use super::*;
280 use crate::*;
281
282 #[derive(Serialize, Deserialize, PartialEq, Debug, Copy, Clone)]
283 struct Position([f32; 3]);
284 #[derive(Serialize, Deserialize, PartialEq, Debug, Copy, Clone)]
285 struct Velocity([f32; 3]);
286
287 struct Context;
288 #[derive(Serialize, Deserialize)]
289 enum ComponentId {
290 Position,
291 Velocity,
292 }
293
294 #[derive(Serialize, Deserialize)]
295 struct SerWorld(#[serde(with = "helpers")] World);
297
298 impl PartialEq for SerWorld {
299 fn eq(&self, other: &Self) -> bool {
300 fn same_components<T: Component + PartialEq>(x: &EntityRef, y: &EntityRef) -> bool {
301 x.get::<&T>().as_deref() == y.get::<&T>().as_deref()
302 }
303
304 for (x, y) in self.0.iter().zip(other.0.iter()) {
305 if x.entity() != y.entity()
306 || !same_components::<Position>(&x, &y)
307 || !same_components::<Velocity>(&x, &y)
308 {
309 return false;
310 }
311 }
312 true
313 }
314 }
315
316 impl fmt::Debug for SerWorld {
317 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
318 f.debug_map()
319 .entries(self.0.iter().map(|e| {
320 (
321 e.entity(),
322 (
323 e.get::<&Position>().map(|x| *x),
324 e.get::<&Velocity>().map(|x| *x),
325 ),
326 )
327 }))
328 .finish()
329 }
330 }
331
332 mod helpers {
333 use super::*;
334 pub fn serialize<S: Serializer>(x: &World, s: S) -> Result<S::Ok, S::Error> {
335 crate::serialize::row::serialize(x, &mut Context, s)
336 }
337 pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<World, D::Error> {
338 crate::serialize::row::deserialize(&mut Context, d)
339 }
340 }
341
342 impl DeserializeContext for Context {
343 fn deserialize_entity<'de, M>(
344 &mut self,
345 mut map: M,
346 entity: &mut EntityBuilder,
347 ) -> Result<(), M::Error>
348 where
349 M: serde::de::MapAccess<'de>,
350 {
351 while let Some(key) = map.next_key()? {
352 match key {
353 ComponentId::Position => {
354 entity.add::<Position>(map.next_value()?);
355 }
356 ComponentId::Velocity => {
357 entity.add::<Velocity>(map.next_value()?);
358 }
359 }
360 }
361 Ok(())
362 }
363 }
364
365 impl SerializeContext for Context {
366 fn serialize_entity<S>(
367 &mut self,
368 entity: EntityRef<'_>,
369 mut map: S,
370 ) -> Result<S::Ok, S::Error>
371 where
372 S: serde::ser::SerializeMap,
373 {
374 try_serialize::<Position, _, _>(&entity, &ComponentId::Position, &mut map)?;
375 try_serialize::<Velocity, _, _>(&entity, &ComponentId::Velocity, &mut map)?;
376 map.end()
377 }
378 }
379
380 #[test]
381 #[rustfmt::skip]
382 fn roundtrip() {
383 use serde_test::{Token, assert_tokens};
384
385 let mut world = World::new();
386 let p0 = Position([0.0, 0.0, 0.0]);
387 let v0 = Velocity([1.0, 1.0, 1.0]);
388 let p1 = Position([2.0, 2.0, 2.0]);
389 let e0 = world.spawn((p0, v0));
390 let e1 = world.spawn((p1,));
391
392 assert_tokens(&SerWorld(world), &[
393 Token::NewtypeStruct { name: "SerWorld" },
394 Token::Map { len: Some(2) },
395
396 Token::U64(e0.to_bits().into()),
397 Token::Map { len: None },
398
399 Token::UnitVariant { name: "ComponentId", variant: "Position" },
400 Token::NewtypeStruct { name: "Position" },
401 Token::Tuple { len: 3 },
402 Token::F32(0.0),
403 Token::F32(0.0),
404 Token::F32(0.0),
405 Token::TupleEnd,
406
407 Token::UnitVariant { name: "ComponentId", variant: "Velocity" },
408 Token::NewtypeStruct { name: "Velocity" },
409 Token::Tuple { len: 3 },
410 Token::F32(1.0),
411 Token::F32(1.0),
412 Token::F32(1.0),
413 Token::TupleEnd,
414
415 Token::MapEnd,
416
417 Token::U64(e1.to_bits().into()),
418 Token::Map { len: None },
419
420 Token::UnitVariant { name: "ComponentId", variant: "Position" },
421 Token::NewtypeStruct { name: "Position" },
422 Token::Tuple { len: 3 },
423 Token::F32(2.0),
424 Token::F32(2.0),
425 Token::F32(2.0),
426 Token::TupleEnd,
427
428 Token::MapEnd,
429
430 Token::MapEnd,
431 ])
432 }
433
434 #[derive(Deserialize)]
435 struct SerSatisfyingWorld<Q>(
437 #[serde(with = "helpers")] World,
438 #[serde(skip)] PhantomData<Q>,
439 );
440
441 impl<Q> PartialEq for SerSatisfyingWorld<Q> {
442 fn eq(&self, other: &Self) -> bool {
443 fn same_components<T: Component + PartialEq>(x: &EntityRef, y: &EntityRef) -> bool {
444 x.get::<&T>().as_deref() == y.get::<&T>().as_deref()
445 }
446
447 for (x, y) in self.0.iter().zip(other.0.iter()) {
448 if x.entity() != y.entity()
449 || !same_components::<Position>(&x, &y)
450 || !same_components::<Velocity>(&x, &y)
451 {
452 return false;
453 }
454 }
455 true
456 }
457 }
458
459 impl<Q> fmt::Debug for SerSatisfyingWorld<Q> {
460 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
461 f.debug_map()
462 .entries(self.0.iter().map(|e| {
463 (
464 e.entity(),
465 (
466 e.get::<&Position>().map(|x| *x),
467 e.get::<&Velocity>().map(|x| *x),
468 ),
469 )
470 }))
471 .finish()
472 }
473 }
474
475 struct SerSatisfyingWorldInner<'a, Q>(&'a World, PhantomData<Q>);
476
477 impl<'a, Q: Query> Serialize for SerSatisfyingWorldInner<'a, Q> {
478 fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
479 crate::serialize::row::serialize_satisfying::<Q, Context, S>(self.0, &mut Context, s)
480 }
481 }
482
483 impl<Q: Query> Serialize for SerSatisfyingWorld<Q> {
484 fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
485 use serde::ser::SerializeTupleStruct;
486 let mut t = s.serialize_tuple_struct("SerSatisfyingWorld", 1)?;
487 t.serialize_field(&SerSatisfyingWorldInner(&self.0, self.1))?;
488 t.end()
489 }
490 }
491
492 #[test]
493 #[rustfmt::skip]
494 fn test_serialize_satisfying() {
495 use serde_test::{Token, assert_tokens, assert_ser_tokens};
496
497 let p0 = Position([0.0, 0.0, 0.0]);
498 let v0 = Velocity([1.0, 1.0, 1.0]);
499 let p1 = Position([2.0, 2.0, 2.0]);
500
501 let world = || {
502 let mut world = World::new();
503 let e0 = world.spawn((p0, v0));
504 let e1 = world.spawn((p1,));
505 (world, e0, e1)
506 };
507
508 let (world0, e00, e01) = world();
509 let (world1, e10, _e11) = world();
510
511 assert_tokens(&SerSatisfyingWorld(world0, PhantomData::<()>), &[
512 Token::TupleStruct { name: "SerSatisfyingWorld", len: 1 },
513 Token::Map { len: Some(2) },
514
515 Token::U64(e00.to_bits().into()),
516 Token::Map { len: None },
517
518 Token::UnitVariant { name: "ComponentId", variant: "Position" },
519 Token::NewtypeStruct { name: "Position" },
520 Token::Tuple { len: 3 },
521 Token::F32(0.0),
522 Token::F32(0.0),
523 Token::F32(0.0),
524 Token::TupleEnd,
525
526 Token::UnitVariant { name: "ComponentId", variant: "Velocity" },
527 Token::NewtypeStruct { name: "Velocity" },
528 Token::Tuple { len: 3 },
529 Token::F32(1.0),
530 Token::F32(1.0),
531 Token::F32(1.0),
532 Token::TupleEnd,
533
534 Token::MapEnd,
535
536 Token::U64(e01.to_bits().into()),
537 Token::Map { len: None },
538
539 Token::UnitVariant { name: "ComponentId", variant: "Position" },
540 Token::NewtypeStruct { name: "Position" },
541 Token::Tuple { len: 3 },
542 Token::F32(2.0),
543 Token::F32(2.0),
544 Token::F32(2.0),
545 Token::TupleEnd,
546 Token::MapEnd,
547 Token::MapEnd,
548
549 Token::TupleStructEnd,
550 ]);
551
552 assert_ser_tokens(&SerSatisfyingWorld(world1, PhantomData::<(&Velocity,)>), &[
553 Token::TupleStruct { name: "SerSatisfyingWorld", len: 1 },
554 Token::Map { len: Some(1) },
555
556 Token::U64(e10.to_bits().into()),
557 Token::Map { len: None },
558
559 Token::UnitVariant { name: "ComponentId", variant: "Position" },
560 Token::NewtypeStruct { name: "Position" },
561 Token::Tuple { len: 3 },
562 Token::F32(0.0),
563 Token::F32(0.0),
564 Token::F32(0.0),
565 Token::TupleEnd,
566
567 Token::UnitVariant { name: "ComponentId", variant: "Velocity" },
568 Token::NewtypeStruct { name: "Velocity" },
569 Token::Tuple { len: 3 },
570 Token::F32(1.0),
571 Token::F32(1.0),
572 Token::F32(1.0),
573 Token::TupleEnd,
574
575 Token::MapEnd,
576
577 Token::MapEnd,
578
579 Token::TupleStructEnd,
580 ])
581 }
582}