scsys_core/id/
identifier.rs

1/*
2    Appellation: id <mod>
3    Contrib: FL03 <jo3mccain@icloud.com>
4*/
5use super::Identifier;
6
7/// [`Id`] is a generic identifier type that wraps a value of type `T`.
8#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
9#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
10#[repr(transparent)]
11pub struct Id<T = usize>(pub T);
12
13impl<T> Id<T> {
14    /// create a new identifier from the given value
15    pub const fn new(id: T) -> Self {
16        Self(id)
17    }
18    #[allow(clippy::should_implement_trait)]
19    /// Create a new identifier with the default value
20    pub fn default() -> Self
21    where
22        T: Default,
23    {
24        Self::new(T::default())
25    }
26    /// returns a new id with a value of `1`
27    pub fn one() -> Self
28    where
29        T: num_traits::One,
30    {
31        Self::new(T::one())
32    }
33    /// returns a new id with a value of `0`
34    pub fn zero() -> Self
35    where
36        T: num_traits::Zero,
37    {
38        Self::new(T::zero())
39    }
40    /// returns an immutable reference to the inner value
41    pub const fn get(&self) -> &T {
42        &self.0
43    }
44    /// returns a mutable reference to the inner value
45    pub const fn get_mut(&mut self) -> &mut T {
46        &mut self.0
47    }
48    /// consumes the current instance to return the inner value
49    #[inline]
50    pub fn value(self) -> T {
51        self.0
52    }
53    /// use the [`replace`](core::mem::replace) method to update and return the inner value
54    pub const fn replace(&mut self, id: T) -> T {
55        core::mem::replace(self.get_mut(), id)
56    }
57    /// mutate the inner value and return a mutable reference to the wrapper for chaining
58    pub fn set(&mut self, id: T) -> &mut Self {
59        *self.get_mut() = id;
60        self
61    }
62    /// [`swap`](core::mem::swap) the inner value with that of another identifier instance of
63    /// the same type `T`
64    pub const fn swap(&mut self, id: &mut Id<T>) {
65        core::mem::swap(self.get_mut(), id.get_mut())
66    }
67    /// [`take`](core::mem::take) the inner value, leaving the logical [`default`](Default::default)
68    /// value in its place.
69    pub fn take(&mut self) -> T
70    where
71        T: Default,
72    {
73        core::mem::take(self.get_mut())
74    }
75    /// consumes the current instance to replace it with another.
76    pub fn with<U>(self, id: U) -> Id<U> {
77        Id::new(id)
78    }
79    /// apply a function onto the inner value and return a new instance with the result
80    pub fn map<U, F>(self, f: F) -> Id<U>
81    where
82        F: FnOnce(T) -> U,
83    {
84        Id::new(f(self.value()))
85    }
86    /// replaces the current id with the next logical value of type `T`
87    ///
88    /// ```rust
89    /// use scsys::Id;
90    ///
91    /// let mut id = Id::zero();
92    /// assert_eq!(id.step(), 0);
93    /// assert_eq!(id.step(), 1);
94    ///
95    /// ```
96    pub fn step(&mut self) -> T
97    where
98        T: num_traits::One,
99        for<'a> &'a T: core::ops::Add<T, Output = T>,
100    {
101        self.replace(self.get() + T::one())
102    }
103    /// returns a new identifier with a reference to the inner value
104    pub const fn view(&self) -> Id<&T> {
105        Id::new(self.get())
106    }
107    /// returns a new identifier with a mutable reference to the inner value
108    pub const fn view_mut(&mut self) -> Id<&mut T> {
109        Id::new(self.get_mut())
110    }
111}
112
113impl<T> Default for Id<T>
114where
115    T: Default,
116{
117    fn default() -> Self {
118        Self::new(T::default())
119    }
120}
121
122impl<T> Identifier for Id<T> {
123    seal!();
124}