use super::Identifier;
#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[repr(transparent)]
pub struct Id<T = usize>(pub T);
impl<T> Id<T> {
pub const fn new(id: T) -> Self {
Self(id)
}
#[allow(clippy::should_implement_trait)]
pub fn default() -> Self
where
T: Default,
{
Self::new(T::default())
}
pub fn one() -> Self
where
T: num_traits::One,
{
Self::new(T::one())
}
pub fn zero() -> Self
where
T: num_traits::Zero,
{
Self::new(T::zero())
}
pub const fn get(&self) -> &T {
&self.0
}
pub const fn get_mut(&mut self) -> &mut T {
&mut self.0
}
#[inline]
pub fn value(self) -> T {
self.0
}
pub const fn replace(&mut self, id: T) -> T {
core::mem::replace(self.get_mut(), id)
}
pub fn set(&mut self, id: T) -> &mut Self {
*self.get_mut() = id;
self
}
pub const fn swap(&mut self, id: &mut Id<T>) {
core::mem::swap(self.get_mut(), id.get_mut())
}
pub fn take(&mut self) -> T
where
T: Default,
{
core::mem::take(self.get_mut())
}
pub fn with<U>(self, id: U) -> Id<U> {
Id::new(id)
}
pub fn map<U, F>(self, f: F) -> Id<U>
where
F: FnOnce(T) -> U,
{
Id::new(f(self.value()))
}
pub fn step(&mut self) -> T
where
T: num_traits::One,
for<'a> &'a T: core::ops::Add<T, Output = T>,
{
self.replace(self.get() + T::one())
}
pub const fn view(&self) -> Id<&T> {
Id::new(self.get())
}
pub const fn view_mut(&mut self) -> Id<&mut T> {
Id::new(self.get_mut())
}
}
impl<T> Default for Id<T>
where
T: Default,
{
fn default() -> Self {
Self::new(T::default())
}
}
impl<T> Identifier for Id<T> {
seal!();
}