use alloc::sync::Arc;
use core::fmt::{Debug, Formatter};
use core::ops::Deref;
use intid_allocator::IdAllocator;
use nonmax::NonMaxUsize;
use parking_lot::Mutex;
static RAW_ID_ALLOCATOR: Mutex<IdAllocator<LiveLocalId>> = Mutex::new(IdAllocator::new());
struct LocalIdInner {
id: LiveLocalId,
}
impl Drop for LocalIdInner {
fn drop(&mut self) {
RAW_ID_ALLOCATOR.lock().free(self.id);
}
}
#[derive(Clone)]
pub struct OwnedLocalId {
_inner: Arc<LocalIdInner>,
id: LiveLocalId,
}
impl OwnedLocalId {
pub fn alloc() -> OwnedLocalId {
let id = RAW_ID_ALLOCATOR.lock().alloc();
OwnedLocalId {
id,
_inner: Arc::new(LocalIdInner { id }),
}
}
#[inline]
pub fn id(&self) -> LiveLocalId {
self.id
}
#[inline]
pub fn index(&self) -> usize {
self.id.0.get()
}
}
impl Debug for OwnedLocalId {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
f.debug_struct("OwnedLocalId")
.field("id", &self.id)
.finish_non_exhaustive()
}
}
impl Deref for OwnedLocalId {
type Target = LiveLocalId;
#[inline]
fn deref(&self) -> &Self::Target {
&self.id
}
}
intid::define_newtype_counter! {
pub struct LiveLocalId(NonMaxUsize);
}