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