use crate::{
StoreContext,
store::{PrunedStore, Store, StoreInner},
};
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct StoreId(u32);
impl StoreId {
pub(super) fn new() -> Self {
use core::sync::atomic::{AtomicU32, Ordering};
static STORE_ID: AtomicU32 = AtomicU32::new(0);
let next = STORE_ID.fetch_add(1, Ordering::AcqRel);
Self(next)
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct Stored<T> {
store: StoreId,
value: T,
}
pub trait AsStoreId: Copy {
fn wrap<T>(self, value: T) -> Stored<T>;
fn unwrap<T>(self, value: &Stored<T>) -> Option<&T>;
}
impl AsStoreId for StoreId {
#[inline]
fn wrap<T>(self, value: T) -> Stored<T> {
Stored { store: self, value }
}
#[inline]
fn unwrap<T>(self, value: &Stored<T>) -> Option<&T> {
if value.store != self {
return None;
}
Some(&value.value)
}
}
impl AsStoreId for &'_ StoreId {
#[inline]
fn wrap<T>(self, value: T) -> Stored<T> {
<StoreId as AsStoreId>::wrap(*self, value)
}
#[inline]
fn unwrap<T>(self, value: &Stored<T>) -> Option<&T> {
<StoreId as AsStoreId>::unwrap(*self, value)
}
}
impl AsStoreId for &'_ StoreInner {
#[inline]
fn wrap<T>(self, value: T) -> Stored<T> {
self.id().wrap(value)
}
#[inline]
fn unwrap<T>(self, value: &Stored<T>) -> Option<&T> {
self.id().unwrap(value)
}
}
impl<D> AsStoreId for &'_ Store<D> {
#[inline]
fn wrap<T>(self, value: T) -> Stored<T> {
self.inner.wrap(value)
}
#[inline]
fn unwrap<T>(self, value: &Stored<T>) -> Option<&T> {
self.inner.unwrap(value)
}
}
impl AsStoreId for &'_ PrunedStore {
#[inline]
fn wrap<T>(self, value: T) -> Stored<T> {
self.inner().wrap(value)
}
#[inline]
fn unwrap<T>(self, value: &Stored<T>) -> Option<&T> {
self.inner().unwrap(value)
}
}
impl<S> AsStoreId for StoreContext<'_, S> {
#[inline]
fn wrap<T>(self, value: T) -> Stored<T> {
self.store.wrap(value)
}
#[inline]
fn unwrap<T>(self, value: &Stored<T>) -> Option<&T> {
self.store.unwrap(value)
}
}