use slotmap::new_key_type;
pub use slotmap::{Key, KeyData};
use std::hash::Hash;
use std::marker::PhantomData;
pub struct Handle<T>(KeyData, PhantomData<T>);
impl<T> Handle<T> {
pub fn null() -> Self {
Key::null()
}
pub fn is_null(&self) -> bool {
Key::is_null(self)
}
pub fn into_untyped(&self) -> HandleUntyped {
HandleUntyped(self.data())
}
pub fn from_untyped(handle: HandleUntyped) -> Handle<T> {
Self(handle.data(), PhantomData)
}
}
new_key_type!(
pub struct HandleUntyped;
);
unsafe impl<T> Key for Handle<T> {
fn data(&self) -> KeyData {
self.0
}
}
impl<T> PartialOrd for Handle<T> {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.0.cmp(&other.0))
}
}
impl<T> Ord for Handle<T> {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.0.cmp(&other.0)
}
}
impl<T> Default for Handle<T> {
fn default() -> Self {
Self(KeyData::default(), PhantomData)
}
}
impl<T> std::fmt::Debug for Handle<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self.0)
}
}
impl<T> Clone for Handle<T> {
fn clone(&self) -> Self {
Self(self.0, PhantomData)
}
}
impl<T> Copy for Handle<T> {}
impl<T> PartialEq for Handle<T> {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
impl<T> Eq for Handle<T> {}
impl<T> Hash for Handle<T> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.0.hash(state)
}
}
impl<T> From<KeyData> for Handle<T> {
fn from(k: KeyData) -> Self {
Self(k, PhantomData)
}
}