reifydb_type/value/uuid/
mod.rs1use std::{
5 cmp::Ordering,
6 fmt,
7 fmt::{Display, Formatter},
8 ops::Deref,
9};
10
11use ::uuid::{Builder, Uuid as StdUuid};
12use reifydb_runtime::context::{clock::Clock, rng::Rng};
13use serde::{Deserialize, Serialize};
14use uuid::Uuid;
15
16pub mod parse;
17
18#[repr(transparent)]
20#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
21pub struct Uuid4(pub StdUuid);
22
23impl Uuid4 {
24 pub fn generate() -> Self {
26 Uuid4(StdUuid::new_v4())
27 }
28}
29
30impl Default for Uuid4 {
31 fn default() -> Self {
32 Self(Uuid::nil())
33 }
34}
35
36impl Deref for Uuid4 {
37 type Target = StdUuid;
38
39 fn deref(&self) -> &Self::Target {
40 &self.0
41 }
42}
43
44impl PartialOrd for Uuid4 {
45 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
46 Some(self.cmp(other))
47 }
48}
49
50impl Ord for Uuid4 {
51 fn cmp(&self, other: &Self) -> Ordering {
52 self.0.as_bytes().cmp(other.0.as_bytes())
53 }
54}
55
56impl From<StdUuid> for Uuid4 {
57 fn from(uuid: StdUuid) -> Self {
58 debug_assert!(uuid.get_version_num() == 4 || uuid.get_version_num() == 0);
59 Uuid4(uuid)
60 }
61}
62
63impl From<Uuid4> for StdUuid {
64 fn from(uuid4: Uuid4) -> Self {
65 uuid4.0
66 }
67}
68
69impl Display for Uuid4 {
70 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
71 write!(f, "{}", self.0)
72 }
73}
74
75#[repr(transparent)]
77#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
78pub struct Uuid7(pub StdUuid);
79
80impl Default for Uuid7 {
81 fn default() -> Self {
82 Self(Uuid::nil())
83 }
84}
85
86impl Uuid7 {
87 pub fn generate(clock: &Clock, rng: &Rng) -> Self {
89 let millis = clock.now_millis();
90 let random_bytes = rng.bytes_10();
91 Uuid7(Builder::from_unix_timestamp_millis(millis, &random_bytes).into_uuid())
92 }
93}
94
95impl Deref for Uuid7 {
96 type Target = StdUuid;
97
98 fn deref(&self) -> &Self::Target {
99 &self.0
100 }
101}
102
103impl PartialOrd for Uuid7 {
104 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
105 Some(self.cmp(other))
106 }
107}
108
109impl Ord for Uuid7 {
110 fn cmp(&self, other: &Self) -> Ordering {
111 self.0.as_bytes().cmp(other.0.as_bytes())
112 }
113}
114
115impl From<StdUuid> for Uuid7 {
116 fn from(uuid: StdUuid) -> Self {
117 debug_assert!(uuid.get_version_num() == 7 || uuid.get_version_num() == 0);
118 Uuid7(uuid)
119 }
120}
121
122impl From<Uuid7> for StdUuid {
123 fn from(uuid7: Uuid7) -> Self {
124 uuid7.0
125 }
126}
127
128impl Display for Uuid7 {
129 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
130 write!(f, "{}", self.0)
131 }
132}
133
134#[cfg(test)]
135#[allow(clippy::approx_constant)]
136pub mod tests {
137 use reifydb_runtime::context::clock::MockClock;
138
139 use super::*;
140
141 fn test_clock_and_rng() -> (MockClock, Clock, Rng) {
142 let mock = MockClock::from_millis(1000);
143 let clock = Clock::Mock(mock.clone());
144 let rng = Rng::seeded(42);
145 (mock, clock, rng)
146 }
147
148 #[test]
149 fn test_uuid4_generate() {
150 let uuid4 = Uuid4::generate();
151 assert_eq!(uuid4.get_version_num(), 4);
152 }
153
154 #[test]
155 fn test_uuid4_equality() {
156 let std_uuid = StdUuid::new_v4();
157 let uuid4_a = Uuid4(std_uuid);
158 let uuid4_b = Uuid4(std_uuid);
159 let uuid4_c = Uuid4::generate();
160
161 assert_eq!(uuid4_a, uuid4_b);
162 assert_ne!(uuid4_a, uuid4_c);
163 }
164
165 #[test]
166 fn test_uuid4_ordering() {
167 let uuid4_a = Uuid4::generate();
168 let uuid4_b = Uuid4::generate();
169
170 let cmp1 = uuid4_a.cmp(&uuid4_b);
171 let cmp2 = uuid4_a.cmp(&uuid4_b);
172 assert_eq!(cmp1, cmp2);
173
174 assert_eq!(uuid4_a.cmp(&uuid4_a), Ordering::Equal);
175 }
176
177 #[test]
178 fn test_uuid4_display() {
179 let std_uuid = StdUuid::new_v4();
180 let uuid4 = Uuid4(std_uuid);
181
182 assert_eq!(format!("{}", uuid4), format!("{}", std_uuid));
183 }
184
185 #[test]
186 fn test_uuid7_generate() {
187 let (_, clock, rng) = test_clock_and_rng();
188 let uuid7 = Uuid7::generate(&clock, &rng);
189 assert_eq!(uuid7.get_version_num(), 7);
190 }
191
192 #[test]
193 fn test_uuid7_equality() {
194 let (mock, clock, rng) = test_clock_and_rng();
195 let uuid7_a = Uuid7::generate(&clock, &rng);
196 let uuid7_b = Uuid7(uuid7_a.0);
197 mock.advance_millis(1);
198 let uuid7_c = Uuid7::generate(&clock, &rng);
199
200 assert_eq!(uuid7_a, uuid7_b);
201 assert_ne!(uuid7_a, uuid7_c);
202 }
203
204 #[test]
205 fn test_uuid7_ordering() {
206 let (mock, clock, rng) = test_clock_and_rng();
207 let uuid7_a = Uuid7::generate(&clock, &rng);
208 mock.advance_millis(1);
209 let uuid7_b = Uuid7::generate(&clock, &rng);
210
211 let cmp1 = uuid7_a.cmp(&uuid7_b);
212 let cmp2 = uuid7_a.cmp(&uuid7_b);
213 assert_eq!(cmp1, cmp2);
214
215 assert_eq!(uuid7_a.cmp(&uuid7_a), Ordering::Equal);
216 }
217
218 #[test]
219 fn test_uuid7_display() {
220 let (_, clock, rng) = test_clock_and_rng();
221 let uuid7 = Uuid7::generate(&clock, &rng);
222 let display = format!("{}", uuid7);
223 assert!(!display.is_empty());
224 }
225
226 #[test]
227 fn test_uuid7_timestamp_ordering() {
228 let (mock, clock, rng) = test_clock_and_rng();
229 let uuid7_first = Uuid7::generate(&clock, &rng);
230 mock.advance_millis(1);
231 let uuid7_second = Uuid7::generate(&clock, &rng);
232
233 assert!(uuid7_first < uuid7_second);
234 }
235}