use core::num::NonZeroU32;
#[cfg(feature = "std")]
pub(crate) const SHARD_BITS: u32 = 6;
#[cfg(feature = "std")]
pub(crate) const NUM_SHARDS: usize = 1 << SHARD_BITS;
#[cfg(feature = "std")]
pub(crate) const LOCAL_BITS: u32 = 32 - SHARD_BITS;
#[cfg(feature = "std")]
pub(crate) const LOCAL_MASK: u32 = (1 << LOCAL_BITS) - 1;
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
#[repr(transparent)]
pub struct Sym(NonZeroU32);
impl Sym {
#[cfg(feature = "std")]
#[inline]
#[cfg_attr(test, mutants::skip)] pub(crate) fn pack(shard: usize, local1: u32) -> Self {
debug_assert!(shard < NUM_SHARDS);
debug_assert!((1..=LOCAL_MASK).contains(&local1));
#[expect(clippy::cast_possible_truncation, reason = "shard < NUM_SHARDS (64) always fits in u32")]
let raw = ((shard as u32) << LOCAL_BITS) | local1;
Self(NonZeroU32::new(raw).expect("local1 >= 1 guarantees a non-zero packed Sym"))
}
#[cfg(feature = "std")]
#[inline]
pub(crate) fn shard(self) -> usize {
(self.0.get() >> LOCAL_BITS) as usize
}
#[cfg(feature = "std")]
#[inline]
pub(crate) fn local1(self) -> u32 {
self.0.get() & LOCAL_MASK
}
#[cfg(feature = "std")]
#[inline]
pub(crate) fn local(self) -> u32 {
self.local1() - 1
}
#[inline]
pub(crate) fn pack_dense(index: usize) -> Self {
let raw = u32::try_from(index)
.ok()
.and_then(|i| NonZeroU32::new(i.wrapping_add(1)))
.expect("internity: dense index exceeds u32");
Self(raw)
}
#[inline]
pub(crate) fn dense(self) -> usize {
(self.0.get() - 1) as usize
}
#[inline]
#[must_use]
pub fn as_u32(self) -> u32 {
self.0.get()
}
#[inline]
#[must_use]
pub fn from_u32(raw: u32) -> Option<Self> {
NonZeroU32::new(raw).map(Self)
}
}
#[inline]
pub(crate) fn dense_index_of(len: usize, sym: Sym) -> Option<usize> {
let index = sym.dense();
(index < len).then_some(index)
}
#[inline]
pub(crate) fn dense_sym_at(len: usize, index: usize) -> Option<Sym> {
(index < len).then(|| Sym::pack_dense(index))
}
impl From<Sym> for u32 {
#[inline]
fn from(sym: Sym) -> Self {
sym.0.get()
}
}
impl core::fmt::Debug for Sym {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_tuple("Sym").field(&self.0.get()).finish()
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(all(test, feature = "std"))]
mod tests {
use super::*;
#[test]
fn roundtrip_pack_unpack() {
for shard in [0usize, 1, 5, 31, 63] {
for local1 in [1u32, 2, 100, LOCAL_MASK] {
let s = Sym::pack(shard, local1);
assert_eq!(s.shard(), shard);
assert_eq!(s.local(), local1 - 1);
}
}
}
}