scsys_core/id/
identifier.rs1use super::Identifier;
6
7#[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 pub const fn new(id: T) -> Self {
16 Self(id)
17 }
18 #[allow(clippy::should_implement_trait)]
19 pub fn default() -> Self
21 where
22 T: Default,
23 {
24 Self::new(T::default())
25 }
26 pub fn one() -> Self
28 where
29 T: num_traits::One,
30 {
31 Self::new(T::one())
32 }
33 pub fn zero() -> Self
35 where
36 T: num_traits::Zero,
37 {
38 Self::new(T::zero())
39 }
40 #[cfg(feature = "rand")]
41 pub fn random() -> Self
42 where
43 rand_distr::StandardUniform: rand_distr::Distribution<T>,
44 {
45 use rand::Rng;
46 let mut rng = rand::rng();
47 Self::new(rng.random())
48 }
49 pub const fn get(&self) -> &T {
51 &self.0
52 }
53 pub const fn get_mut(&mut self) -> &mut T {
55 &mut self.0
56 }
57 #[inline]
59 pub fn value(self) -> T {
60 self.0
61 }
62 pub const fn replace(&mut self, id: T) -> T {
64 core::mem::replace(self.get_mut(), id)
65 }
66 pub fn set(&mut self, id: T) -> &mut Self {
68 *self.get_mut() = id;
69 self
70 }
71 pub const fn swap(&mut self, id: &mut Id<T>) {
74 core::mem::swap(self.get_mut(), id.get_mut())
75 }
76 pub fn take(&mut self) -> T
79 where
80 T: Default,
81 {
82 core::mem::take(self.get_mut())
83 }
84 pub fn with<U>(self, id: U) -> Id<U> {
86 Id::new(id)
87 }
88 pub fn map<U, F>(self, f: F) -> Id<U>
90 where
91 F: FnOnce(T) -> U,
92 {
93 Id::new(f(self.value()))
94 }
95 pub fn step(&mut self) -> T
106 where
107 T: num_traits::One,
108 for<'a> &'a T: core::ops::Add<T, Output = T>,
109 {
110 self.replace(self.get() + T::one())
111 }
112 pub const fn view(&self) -> Id<&T> {
114 Id::new(self.get())
115 }
116 pub const fn view_mut(&mut self) -> Id<&mut T> {
118 Id::new(self.get_mut())
119 }
120}
121
122impl Id<usize> {
123 pub fn atomic() -> Self {
124 use core::sync::atomic::{AtomicUsize, Ordering::Relaxed};
125 static COUNTER: AtomicUsize = AtomicUsize::new(1);
126 Self::new(COUNTER.fetch_add(1, Relaxed))
127 }
128 pub fn atomic_step(&mut self) -> usize {
131 use core::sync::atomic::{AtomicUsize, Ordering::Relaxed};
132 static COUNTER: AtomicUsize = AtomicUsize::new(1);
133 self.replace(COUNTER.fetch_add(1, Relaxed))
134 }
135}
136
137#[cfg(feature = "uuid")]
138impl Id<uuid::Uuid> {
139 pub fn v3(namespace: &uuid::Uuid, name: &[u8]) -> Self {
140 let id = uuid::Uuid::new_v3(namespace, name);
141 Self::new(id)
142 }
143
144 #[cfg(all(feature = "rng", feature = "uuid"))]
145 pub fn v4() -> Self {
146 let id = uuid::Uuid::new_v4();
147 Self::new(id)
148 }
149}
150
151impl<T> Default for Id<T>
152where
153 T: Default,
154{
155 fn default() -> Self {
156 Self::new(T::default())
157 }
158}
159
160impl<T> Identifier for Id<T> {
161 seal!();
162}