use super::{EngineIdx, Guarded};
use crate::{
collections::arena::{ArenaIndex, DedupArena, GuardedEntity},
FuncType,
};
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct DedupFuncTypeIdx(u32);
impl ArenaIndex for DedupFuncTypeIdx {
fn into_usize(self) -> usize {
self.0 as _
}
fn from_usize(value: usize) -> Self {
let value = value.try_into().unwrap_or_else(|error| {
panic!("index {value} is out of bounds as dedup func type index: {error}")
});
Self(value)
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[repr(transparent)]
pub struct DedupFuncType(GuardedEntity<EngineIdx, DedupFuncTypeIdx>);
impl DedupFuncType {
pub(super) fn from_inner(stored: GuardedEntity<EngineIdx, DedupFuncTypeIdx>) -> Self {
Self(stored)
}
pub(super) fn into_inner(self) -> GuardedEntity<EngineIdx, DedupFuncTypeIdx> {
self.0
}
}
#[derive(Debug)]
pub struct FuncTypeRegistry {
engine_idx: EngineIdx,
func_types: DedupArena<DedupFuncTypeIdx, FuncType>,
}
impl FuncTypeRegistry {
pub(crate) fn new(engine_idx: EngineIdx) -> Self {
Self {
engine_idx,
func_types: DedupArena::default(),
}
}
fn unwrap_index<Idx>(&self, func_type: Guarded<Idx>) -> Idx
where
Idx: ArenaIndex,
{
func_type.entity_index(self.engine_idx).unwrap_or_else(|| {
panic!(
"encountered foreign entity in func type registry: {}",
self.engine_idx.into_usize()
)
})
}
pub(crate) fn alloc_func_type(&mut self, func_type: FuncType) -> DedupFuncType {
DedupFuncType::from_inner(Guarded::new(
self.engine_idx,
self.func_types.alloc(func_type),
))
}
pub(crate) fn resolve_func_type(&self, func_type: &DedupFuncType) -> &FuncType {
let entity_index = self.unwrap_index(func_type.into_inner());
self.func_types
.get(entity_index)
.unwrap_or_else(|| panic!("failed to resolve stored function type: {entity_index:?}"))
}
}