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}