1use crate::{
2 archetypes::DeserializeArchetypes,
3 entity::allocator::DeserializeAllocator,
4 registry,
5 resource,
6 World,
7};
8use core::{
9 fmt,
10 marker::PhantomData,
11};
12use serde::{
13 de,
14 de::{
15 SeqAccess,
16 Visitor,
17 },
18 ser::SerializeTuple,
19 Deserializer,
20 Serializer,
21};
22
23impl<Registry, Resources> serde::Serialize for World<Registry, Resources>
24where
25 Registry: registry::Serialize,
26 Resources: resource::Resources + resource::Serialize,
27{
28 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
29 where
30 S: Serializer,
31 {
32 let mut tuple = serializer.serialize_tuple(3)?;
33 tuple.serialize_element(&self.archetypes)?;
34 tuple.serialize_element(&self.entity_allocator)?;
35 tuple.serialize_element(&resource::Serializer(&self.resources))?;
36 tuple.end()
37 }
38}
39
40impl<'de, Registry, Resources> serde::Deserialize<'de> for World<Registry, Resources>
41where
42 Registry: registry::Deserialize<'de>,
43 Resources: resource::Resources + resource::Deserialize<'de>,
44{
45 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
46 where
47 D: Deserializer<'de>,
48 {
49 struct WorldVisitor<'de, Registry, Resources>
50 where
51 Registry: registry::Deserialize<'de>,
52 {
53 lifetime: PhantomData<&'de ()>,
54 registry: PhantomData<Registry>,
55 resources: PhantomData<Resources>,
56 }
57
58 impl<'de, Registry, Resources> Visitor<'de> for WorldVisitor<'de, Registry, Resources>
59 where
60 Registry: registry::Deserialize<'de>,
61 Resources: resource::Resources + resource::Deserialize<'de>,
62 {
63 type Value = World<Registry, Resources>;
64
65 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
66 formatter.write_str("serialized World")
67 }
68
69 fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
70 where
71 V: SeqAccess<'de>,
72 {
73 let mut len = 0;
74 let archetypes = seq
75 .next_element_seed(DeserializeArchetypes::new(&mut len))?
76 .ok_or_else(|| de::Error::invalid_length(0, &self))?;
77 let entity_allocator = seq
78 .next_element_seed(DeserializeAllocator::new(&archetypes))?
79 .ok_or_else(|| de::Error::invalid_length(1, &self))?;
80 let resources: resource::Deserializer<Resources> = seq
81 .next_element()?
82 .ok_or_else(|| de::Error::invalid_length(2, &self))?;
83 Ok(World::from_raw_parts(
84 archetypes,
85 entity_allocator,
86 len,
87 resources.0,
88 ))
89 }
90 }
91
92 deserializer.deserialize_tuple(
93 3,
94 WorldVisitor::<Registry, Resources> {
95 lifetime: PhantomData,
96 registry: PhantomData,
97 resources: PhantomData,
98 },
99 )
100 }
101}
102
103#[cfg(test)]
104mod tests {
105 use super::World;
106 use crate::{
107 entity,
108 resources,
109 Registry,
110 Resources,
111 };
112 use alloc::vec;
113 use claims::{
114 assert_err_eq,
115 assert_ok,
116 assert_ok_eq,
117 };
118 use serde::{
119 de::Error as _,
120 Deserialize,
121 Serialize,
122 };
123 use serde_assert::{
124 de::Error,
125 Deserializer,
126 Serializer,
127 Token,
128 Tokens,
129 };
130 use serde_derive::{
131 Deserialize,
132 Serialize,
133 };
134
135 #[derive(Debug, Deserialize, Eq, PartialEq, Serialize)]
136 struct A(u32);
137
138 #[derive(Debug, Deserialize, Eq, PartialEq, Serialize)]
139 struct B(char);
140
141 type Registry = Registry!(A, B);
142
143 #[test]
144 fn serialize_deserialize_empty() {
145 let world = World::<Registry>::new();
146
147 let serializer = Serializer::builder().build();
148 let tokens = assert_ok_eq!(
149 world.serialize(&serializer),
150 Tokens(vec![
151 Token::Tuple { len: 3 },
152 Token::Seq { len: Some(0) },
154 Token::SeqEnd,
155 Token::Struct {
157 name: "Allocator",
158 len: 2,
159 },
160 Token::Field("length"),
161 Token::U64(0),
162 Token::Field("free"),
163 Token::Seq { len: Some(0) },
164 Token::SeqEnd,
165 Token::StructEnd,
166 Token::Tuple { len: 0 },
168 Token::TupleEnd,
169 Token::TupleEnd,
170 ])
171 );
172 let mut deserializer = Deserializer::builder().tokens(tokens).build();
173 assert_ok_eq!(
174 World::<Registry, Resources!()>::deserialize(&mut deserializer),
175 world
176 );
177 }
178
179 #[test]
180 fn serialize_deserialize_after_mutation() {
181 let mut world = World::<Registry>::new();
182
183 let entity_identifier = world.insert(entity!(A(1), B('a')));
184 world.remove(entity_identifier);
185 world.insert(entity!(A(2), B('b')));
186 world.insert(entity!(A(3), B('c')));
187 world.insert(entity!(A(4), B('d')));
188 world.insert(entity!(A(5)));
189 world.insert(entity!(A(6)));
190 world.insert(entity!());
191 let entity_identifier = world.insert(entity!(B('g')));
192 world.remove(entity_identifier);
193 let entity_identifier = world.insert(entity!(B('h')));
194 world.remove(entity_identifier);
195
196 let serializer = Serializer::builder().is_human_readable(false).build();
197 let tokens = assert_ok_eq!(
198 world.serialize(&serializer),
199 Tokens(vec![
200 Token::Tuple { len: 3 },
201 Token::Seq { len: Some(4) },
203 Token::Unordered(&[
204 &[
206 Token::NewtypeStruct { name: "Archetype" },
207 Token::Tuple { len: 3 },
208 Token::Tuple { len: 1 },
210 Token::U8(0),
211 Token::TupleEnd,
212 Token::U64(1),
214 Token::Tuple { len: 1 },
216 Token::Tuple { len: 1 },
218 Token::Struct {
219 name: "Identifier",
220 len: 2,
221 },
222 Token::Field("index"),
223 Token::U64(5),
224 Token::Field("generation"),
225 Token::U64(0),
226 Token::StructEnd,
227 Token::TupleEnd,
228 Token::TupleEnd,
229 Token::TupleEnd,
230 ],
231 &[
233 Token::NewtypeStruct { name: "Archetype" },
234 Token::Tuple { len: 3 },
235 Token::Tuple { len: 1 },
237 Token::U8(1),
238 Token::TupleEnd,
239 Token::U64(2),
241 Token::Tuple { len: 2 },
243 Token::Tuple { len: 2 },
245 Token::Struct {
246 name: "Identifier",
247 len: 2,
248 },
249 Token::Field("index"),
250 Token::U64(3),
251 Token::Field("generation"),
252 Token::U64(0),
253 Token::StructEnd,
254 Token::Struct {
255 name: "Identifier",
256 len: 2,
257 },
258 Token::Field("index"),
259 Token::U64(4),
260 Token::Field("generation"),
261 Token::U64(0),
262 Token::StructEnd,
263 Token::TupleEnd,
264 Token::Tuple { len: 2 },
266 Token::NewtypeStruct { name: "A" },
267 Token::U32(5),
268 Token::NewtypeStruct { name: "A" },
269 Token::U32(6),
270 Token::TupleEnd,
271 Token::TupleEnd,
272 Token::TupleEnd,
273 ],
274 &[
276 Token::NewtypeStruct { name: "Archetype" },
277 Token::Tuple { len: 3 },
278 Token::Tuple { len: 1 },
280 Token::U8(2),
281 Token::TupleEnd,
282 Token::U64(0),
284 Token::Tuple { len: 2 },
286 Token::Tuple { len: 0 },
288 Token::TupleEnd,
289 Token::Tuple { len: 0 },
291 Token::TupleEnd,
292 Token::TupleEnd,
293 Token::TupleEnd,
294 ],
295 &[
297 Token::NewtypeStruct { name: "Archetype" },
298 Token::Tuple { len: 3 },
299 Token::Tuple { len: 1 },
301 Token::U8(3),
302 Token::TupleEnd,
303 Token::U64(3),
305 Token::Tuple { len: 3 },
307 Token::Tuple { len: 3 },
309 Token::Struct {
310 name: "Identifier",
311 len: 2,
312 },
313 Token::Field("index"),
314 Token::U64(0),
315 Token::Field("generation"),
316 Token::U64(1),
317 Token::StructEnd,
318 Token::Struct {
319 name: "Identifier",
320 len: 2,
321 },
322 Token::Field("index"),
323 Token::U64(1),
324 Token::Field("generation"),
325 Token::U64(0),
326 Token::StructEnd,
327 Token::Struct {
328 name: "Identifier",
329 len: 2,
330 },
331 Token::Field("index"),
332 Token::U64(2),
333 Token::Field("generation"),
334 Token::U64(0),
335 Token::StructEnd,
336 Token::TupleEnd,
337 Token::Tuple { len: 3 },
339 Token::NewtypeStruct { name: "A" },
340 Token::U32(2),
341 Token::NewtypeStruct { name: "A" },
342 Token::U32(3),
343 Token::NewtypeStruct { name: "A" },
344 Token::U32(4),
345 Token::TupleEnd,
346 Token::Tuple { len: 3 },
348 Token::NewtypeStruct { name: "B" },
349 Token::Char('b'),
350 Token::NewtypeStruct { name: "B" },
351 Token::Char('c'),
352 Token::NewtypeStruct { name: "B" },
353 Token::Char('d'),
354 Token::TupleEnd,
355 Token::TupleEnd,
356 Token::TupleEnd,
357 ],
358 ]),
359 Token::SeqEnd,
360 Token::Struct {
362 name: "Allocator",
363 len: 2,
364 },
365 Token::Field("length"),
366 Token::U64(7),
367 Token::Field("free"),
368 Token::Seq { len: Some(1) },
369 Token::Struct {
370 name: "Identifier",
371 len: 2,
372 },
373 Token::Field("index"),
374 Token::U64(6),
375 Token::Field("generation"),
376 Token::U64(1),
377 Token::StructEnd,
378 Token::SeqEnd,
379 Token::StructEnd,
380 Token::Tuple { len: 0 },
382 Token::TupleEnd,
383 Token::TupleEnd,
384 ])
385 );
386 let mut deserializer = Deserializer::builder()
387 .tokens(tokens)
388 .is_human_readable(false)
389 .build();
390 assert_ok_eq!(
391 World::<Registry, Resources!()>::deserialize(&mut deserializer),
392 world
393 );
394 }
395
396 #[test]
397 fn serialize_deserialize_with_resources() {
398 let world = World::<Registry!(), _>::with_resources(resources!(A(42), B('a')));
399
400 let serializer = Serializer::builder().is_human_readable(false).build();
401 let tokens = assert_ok_eq!(
402 world.serialize(&serializer),
403 Tokens(vec![
404 Token::Tuple { len: 3 },
405 Token::Seq { len: Some(0) },
407 Token::SeqEnd,
408 Token::Struct {
410 name: "Allocator",
411 len: 2,
412 },
413 Token::Field("length"),
414 Token::U64(0),
415 Token::Field("free"),
416 Token::Seq { len: Some(0) },
417 Token::SeqEnd,
418 Token::StructEnd,
419 Token::Tuple { len: 2 },
421 Token::NewtypeStruct { name: "A" },
422 Token::U32(42),
423 Token::NewtypeStruct { name: "B" },
424 Token::Char('a'),
425 Token::TupleEnd,
426 Token::TupleEnd,
427 ])
428 );
429 let mut deserializer = Deserializer::builder().tokens(tokens).build();
430 assert_ok_eq!(
431 World::<Registry!(), _>::deserialize(&mut deserializer),
432 world
433 );
434 }
435
436 #[test]
437 fn deserialize_missing_archetypes() {
438 let mut deserializer = Deserializer::builder()
439 .tokens(Tokens(vec![Token::Tuple { len: 0 }, Token::TupleEnd]))
440 .is_human_readable(false)
441 .build();
442
443 assert_err_eq!(
444 World::<Registry, Resources!()>::deserialize(&mut deserializer),
445 Error::invalid_length(0, &"serialized World")
446 );
447 }
448
449 #[test]
450 fn deserialize_missing_entity_allocator() {
451 let mut deserializer = Deserializer::builder()
452 .tokens(Tokens(vec![
453 Token::Tuple { len: 1 },
454 Token::Seq { len: Some(0) },
456 Token::SeqEnd,
457 Token::TupleEnd,
458 ]))
459 .is_human_readable(false)
460 .build();
461
462 assert_err_eq!(
463 World::<Registry, Resources!()>::deserialize(&mut deserializer),
464 Error::invalid_length(1, &"serialized World")
465 );
466 }
467
468 #[test]
469 fn deserialize_missing_resources() {
470 let mut deserializer = Deserializer::builder()
471 .tokens(Tokens(vec![
472 Token::Tuple { len: 2 },
473 Token::Seq { len: Some(0) },
475 Token::SeqEnd,
476 Token::Struct {
478 name: "Allocator",
479 len: 2,
480 },
481 Token::Field("length"),
482 Token::U64(0),
483 Token::Field("free"),
484 Token::Seq { len: Some(0) },
485 Token::SeqEnd,
486 Token::StructEnd,
487 Token::TupleEnd,
488 ]))
489 .is_human_readable(false)
490 .build();
491
492 assert_err_eq!(
493 World::<Registry, Resources!()>::deserialize(&mut deserializer),
494 Error::invalid_length(2, &"serialized World")
495 );
496 }
497
498 #[test]
499 fn deserialize_then_mutate() {
500 let mut world = World::<Registry>::new();
501 world.insert(entity!(A(0)));
502
503 let serializer = Serializer::builder().build();
504 let tokens = assert_ok!(world.serialize(&serializer));
505
506 let mut deserializer = Deserializer::builder().tokens(tokens).build();
507 let mut deserialized_world = assert_ok!(World::<Registry, Resources!()>::deserialize(
508 &mut deserializer
509 ));
510
511 world.insert(entity!(A(1)));
512 deserialized_world.insert(entity!(A(1)));
513
514 assert_eq!(world, deserialized_world);
515 }
516}