use crate::types::EntityTag;
use std::{fmt, mem::size_of};
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub(crate) struct IndexId {
entity_tag: EntityTag,
ordinal: u16,
generation: u64,
}
impl IndexId {
pub(crate) const STORED_SIZE_USIZE: usize =
size_of::<u64>() + size_of::<u16>() + size_of::<u64>();
#[must_use]
#[cfg(test)]
pub(crate) const fn new(entity_tag: EntityTag, ordinal: u16) -> Self {
Self {
entity_tag,
ordinal,
generation: 0,
}
}
#[must_use]
pub(crate) const fn new_with_generation(
entity_tag: EntityTag,
ordinal: u16,
generation: u64,
) -> Self {
Self {
entity_tag,
ordinal,
generation,
}
}
#[must_use]
pub(crate) const fn entity_tag(&self) -> EntityTag {
self.entity_tag
}
#[must_use]
#[cfg(test)]
pub(crate) const fn ordinal(&self) -> u16 {
self.ordinal
}
#[must_use]
pub(crate) const fn generation(&self) -> u64 {
self.generation
}
#[must_use]
pub(crate) fn to_bytes(self) -> [u8; Self::STORED_SIZE_USIZE] {
let mut out = [0u8; Self::STORED_SIZE_USIZE];
let entity = self.entity_tag.value().to_be_bytes();
let ordinal = self.ordinal.to_be_bytes();
let generation = self.generation.to_be_bytes();
out[..size_of::<u64>()].copy_from_slice(&entity);
let ordinal_end = size_of::<u64>() + size_of::<u16>();
out[size_of::<u64>()..ordinal_end].copy_from_slice(&ordinal);
out[ordinal_end..].copy_from_slice(&generation);
out
}
pub(crate) fn from_bytes(bytes: &[u8]) -> Option<Self> {
if bytes.len() != Self::STORED_SIZE_USIZE {
return None;
}
let mut entity = [0u8; size_of::<u64>()];
entity.copy_from_slice(&bytes[..size_of::<u64>()]);
let mut ordinal = [0u8; size_of::<u16>()];
let ordinal_end = size_of::<u64>() + size_of::<u16>();
ordinal.copy_from_slice(&bytes[size_of::<u64>()..ordinal_end]);
let mut generation = [0u8; size_of::<u64>()];
generation.copy_from_slice(&bytes[ordinal_end..]);
Some(Self::new_with_generation(
EntityTag::new(u64::from_be_bytes(entity)),
u16::from_be_bytes(ordinal),
u64::from_be_bytes(generation),
))
}
}
impl fmt::Display for IndexId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}:{}@{}",
self.entity_tag.value(),
self.ordinal,
self.generation
)
}
}