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