brood/world/
impl_serde.rs

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                // Archetypes
153                Token::Seq { len: Some(0) },
154                Token::SeqEnd,
155                // Entity Allocator
156                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                // Resources
167                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                // Archetypes
202                Token::Seq { len: Some(4) },
203                Token::Unordered(&[
204                    // No component Archetype
205                    &[
206                        Token::NewtypeStruct { name: "Archetype" },
207                        Token::Tuple { len: 3 },
208                        // Identifier
209                        Token::Tuple { len: 1 },
210                        Token::U8(0),
211                        Token::TupleEnd,
212                        // Length
213                        Token::U64(1),
214                        // Columns
215                        Token::Tuple { len: 1 },
216                        // Entity identifiers
217                        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                    // A Archetype
232                    &[
233                        Token::NewtypeStruct { name: "Archetype" },
234                        Token::Tuple { len: 3 },
235                        // Identifier
236                        Token::Tuple { len: 1 },
237                        Token::U8(1),
238                        Token::TupleEnd,
239                        // Length
240                        Token::U64(2),
241                        // Columns
242                        Token::Tuple { len: 2 },
243                        // Entity identifiers
244                        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                        // A column
265                        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                    // B Archetype
275                    &[
276                        Token::NewtypeStruct { name: "Archetype" },
277                        Token::Tuple { len: 3 },
278                        // Identifier
279                        Token::Tuple { len: 1 },
280                        Token::U8(2),
281                        Token::TupleEnd,
282                        // Length
283                        Token::U64(0),
284                        // Columns
285                        Token::Tuple { len: 2 },
286                        // Entity identifiers
287                        Token::Tuple { len: 0 },
288                        Token::TupleEnd,
289                        // B column
290                        Token::Tuple { len: 0 },
291                        Token::TupleEnd,
292                        Token::TupleEnd,
293                        Token::TupleEnd,
294                    ],
295                    // AB Archetype
296                    &[
297                        Token::NewtypeStruct { name: "Archetype" },
298                        Token::Tuple { len: 3 },
299                        // Identifier
300                        Token::Tuple { len: 1 },
301                        Token::U8(3),
302                        Token::TupleEnd,
303                        // Length
304                        Token::U64(3),
305                        // Columns
306                        Token::Tuple { len: 3 },
307                        // Entity identifiers
308                        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                        // A column
338                        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                        // B column
347                        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                // Entity Allocator
361                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                // Resources
381                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                // Archetypes
406                Token::Seq { len: Some(0) },
407                Token::SeqEnd,
408                // Entity Allocator
409                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                // Resources
420                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                // Archetypes
455                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                // Archetypes
474                Token::Seq { len: Some(0) },
475                Token::SeqEnd,
476                // Entity allocator
477                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}