scsys_core/id/
identifier.rs1#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
7#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
8#[repr(transparent)]
9pub struct Id<T = usize>(pub T);
10
11impl<T> Id<T> {
12 pub fn new() -> Self
14 where
15 T: Default,
16 {
17 Self(T::default())
18 }
19 pub fn from_value(id: T) -> Self {
21 Self(id)
22 }
23 #[cfg(feature = "rand")]
24 pub fn random() -> Self
25 where
26 rand_distr::StandardUniform: rand_distr::Distribution<T>,
27 {
28 use rand::Rng;
29 let mut rng = rand::rng();
30 Self::from_value(rng.random())
31 }
32 pub const fn get(&self) -> &T {
34 &self.0
35 }
36 pub fn get_mut(&mut self) -> &mut T {
38 &mut self.0
39 }
40 pub fn into_inner(self) -> T {
42 self.0
43 }
44 pub fn replace(&mut self, id: T) -> T {
46 core::mem::replace(self.get_mut(), id)
47 }
48 pub fn set(&mut self, id: T) -> &mut Self {
50 *self.get_mut() = id;
51 self
52 }
53 pub fn take(&mut self) -> T
55 where
56 T: Default,
57 {
58 core::mem::take(self.get_mut())
59 }
60 pub fn with<U>(self, id: U) -> Id<U> {
62 Id(id)
63 }
64 pub fn map<U, F>(self, f: F) -> Id<U>
66 where
67 F: FnOnce(T) -> U,
68 {
69 Id(f(self.0))
70 }
71}
72
73impl Id<usize> {
74 pub fn atomic() -> Self {
75 use core::sync::atomic::{AtomicUsize, Ordering::Relaxed};
76 static COUNTER: AtomicUsize = AtomicUsize::new(1);
77 Self(COUNTER.fetch_add(1, Relaxed))
78 }
79
80 pub fn next(&self) -> Self {
81 Self::atomic()
82 }
83}
84
85#[cfg(feature = "uuid")]
86impl Id<uuid::Uuid> {
87 pub fn v3(namespace: &uuid::Uuid, name: &[u8]) -> Self {
88 let id = uuid::Uuid::new_v3(&namespace, name);
89 Self(id)
90 }
91
92 #[cfg(all(feature = "rng", feature = "uuid"))]
93 pub fn v4() -> Self {
94 let id = uuid::Uuid::new_v4();
95 Self(id)
96 }
97}
98
99impl<T> crate::id::Identifier for Id<T> {
100 seal!();
101}
102
103impl<T: Default> Default for Id<T> {
104 fn default() -> Self {
105 Self::new()
106 }
107}
108
109impl<T> AsRef<T> for Id<T> {
110 fn as_ref(&self) -> &T {
111 &self.0
112 }
113}
114
115impl<T> AsMut<T> for Id<T> {
116 fn as_mut(&mut self) -> &mut T {
117 &mut self.0
118 }
119}
120
121impl<T> core::borrow::Borrow<T> for Id<T> {
122 fn borrow(&self) -> &T {
123 &self.0
124 }
125}
126
127impl<T> core::borrow::BorrowMut<T> for Id<T> {
128 fn borrow_mut(&mut self) -> &mut T {
129 &mut self.0
130 }
131}
132
133impl<T> core::ops::Deref for Id<T> {
134 type Target = T;
135
136 fn deref(&self) -> &Self::Target {
137 &self.0
138 }
139}
140
141impl<T> core::ops::DerefMut for Id<T> {
142 fn deref_mut(&mut self) -> &mut Self::Target {
143 &mut self.0
144 }
145}
146
147macro_rules! fmt_atomic {
148 ($s:ident {$($trait:ident($($fmt:tt)*)),* $(,)?}) => {
149 $(
150 fmt_atomic!(@impl $s::$trait($($fmt)*));
151 )*
152 };
153 (@impl $s:ident::$trait:ident($($fmt:tt)*)) => {
154 impl<T> ::core::fmt::$trait for Id<T>
155 where
156 T: ::core::fmt::$trait
157 {
158 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
159 write!(f, $($fmt)*, self.0)
160 }
161 }
162 };
163}
164
165fmt_atomic! {
166 Id {
167 Binary("{:b}"),
168 Debug("{:?}"),
169 Display("{}"),
170 LowerExp("{:e}"),
171 LowerHex("{:x}"),
172 Octal("{:o}"),
173 UpperExp("{:E}"),
174 UpperHex("{:X}")
175 }
176}
177
178impl<S> PartialEq<S> for Id
179where
180 usize: PartialEq<S>,
181{
182 fn eq(&self, other: &S) -> bool {
183 self.0.eq(other)
184 }
185}