use core::fmt::{self, Formatter};
use bevy::{
ecs::entity::{EntityGeneration, EntityIndex},
prelude::*,
};
use serde::{
Deserializer, Serialize, Serializer,
de::{self, SeqAccess, Visitor},
};
pub fn serialize<S: Serializer>(entity: &Entity, serializer: S) -> Result<S::Ok, S::Error> {
let mut index = entity.index_u32() << 1;
let has_generation = entity.generation() != EntityGeneration::FIRST;
index |= has_generation as u32;
if has_generation {
let generation = entity.generation().to_bits();
(index, generation).serialize(serializer)
} else {
index.serialize(serializer)
}
}
pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Entity, D::Error> {
deserializer.deserialize_tuple(2, EntityVisitor)
}
struct EntityVisitor;
impl<'de> Visitor<'de> for EntityVisitor {
type Value = Entity;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("entity index with optional generation")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
let index: u32 = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
let has_generation = (index & 1) != 0;
let generation = if has_generation {
seq.next_element()?
.ok_or_else(|| de::Error::invalid_length(1, &self))?
} else {
0
};
let row = unsafe { EntityIndex::from_raw_u32(index >> 1).unwrap_unchecked() };
let generation = EntityGeneration::from_bits(generation);
Ok(Entity::from_index_and_generation(row, generation))
}
}