1#![doc(html_root_url = "https://docs.rs/uuid-rs")]
20
21mod name;
22mod rand;
23mod time;
24
25use core::fmt;
26use core::sync::atomic;
27use std::time::SystemTime;
28
29pub const UTC_EPOCH: u64 = 0x1B21_DD21_3814_000;
31
32#[derive(Debug)]
34pub struct Layout {
35 pub field_low: u32,
37 pub field_mid: u16,
39 pub field_high_and_version: u16,
41 pub clock_seq_high_and_reserved: u8,
43 pub clock_seq_low: u8,
45 pub node: [u8; 6],
47}
48
49impl Layout {
50 pub fn as_fields(&self) -> (u32, u16, u16, u16, u64) {
52 (
53 self.field_low,
54 self.field_mid,
55 self.field_high_and_version,
56 ((self.clock_seq_high_and_reserved as u16) << 8) | self.clock_seq_low as u16,
57 (self.node[0] as u64) << 40
58 | (self.node[1] as u64) << 32
59 | (self.node[2] as u64) << 24
60 | (self.node[3] as u64) << 16
61 | (self.node[4] as u64) << 8
62 | (self.node[5] as u64),
63 )
64 }
65
66 pub fn as_bytes(&self) -> UUID {
68 UUID([
69 self.field_low.to_be_bytes()[0],
70 self.field_low.to_be_bytes()[1],
71 self.field_low.to_be_bytes()[2],
72 self.field_low.to_be_bytes()[3],
73 self.field_mid.to_be_bytes()[0],
74 self.field_mid.to_be_bytes()[1],
75 self.field_high_and_version.to_be_bytes()[0],
76 self.field_high_and_version.to_be_bytes()[1],
77 self.clock_seq_high_and_reserved,
78 self.clock_seq_low,
79 self.node[0],
80 self.node[1],
81 self.node[2],
82 self.node[3],
83 self.node[4],
84 self.node[5],
85 ])
86 }
87
88 pub fn get_version(&self) -> Option<Version> {
90 match (self.field_high_and_version >> 12) & 0xf {
91 0x01 => Some(Version::TIME),
92 0x02 => Some(Version::DCE),
93 0x03 => Some(Version::MD5),
94 0x04 => Some(Version::RAND),
95 0x05 => Some(Version::SHA1),
96 _ => None,
97 }
98 }
99
100 pub fn get_variant(&self) -> Option<Variant> {
102 match (self.clock_seq_high_and_reserved >> 4) & 0xf {
103 0x00 => Some(Variant::NCS),
104 0x01 => Some(Variant::RFC),
105 0x02 => Some(Variant::MS),
106 0x03 => Some(Variant::FUT),
107 _ => None,
108 }
109 }
110
111 pub fn get_time(&self) -> u64 {
113 self.field_low as u64
114 }
115
116 pub fn get_mac(&self) -> Node {
118 Node(self.node)
119 }
120}
121
122#[derive(Debug, Copy, Clone)]
124pub enum Domain {
125 PERSON = 0,
126 GROUP,
127 ORG,
128}
129
130#[derive(Debug, Eq, PartialEq)]
132pub enum Variant {
133 NCS = 0,
135 RFC,
137 MS,
139 FUT,
141}
142
143#[derive(Debug, Eq, PartialEq)]
145pub enum Version {
146 TIME = 1,
148 DCE,
150 MD5,
152 RAND,
154 SHA1,
156}
157
158#[derive(Debug, Eq, PartialEq)]
161pub struct Timestamp(u64);
162
163impl Timestamp {
164 pub fn new() -> u64 {
166 let utc = SystemTime::now()
167 .duration_since(SystemTime::UNIX_EPOCH)
168 .unwrap()
169 .checked_add(std::time::Duration::from_nanos(UTC_EPOCH))
170 .unwrap()
171 .as_nanos();
172
173 (utc & 0xffff_ffff_ffff_ffff) as u64
174 }
175}
176
177#[derive(Debug, Eq, PartialEq, Copy, Clone)]
179pub struct UUID([u8; 16]);
180
181impl UUID {
182 pub const NIL: Self = UUID([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
184
185 pub const NAMESPACE_DNS: Self = UUID([
187 0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30,
188 0xc8,
189 ]);
190
191 pub const NAMESPACE_OID: Self = UUID([
193 0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30,
194 0xc8,
195 ]);
196
197 pub const NAMESPACE_URL: Self = UUID([
199 0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30,
200 0xc8,
201 ]);
202
203 pub const NAMESPACE_X500: Self = UUID([
205 0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30,
206 0xc8,
207 ]);
208}
209
210impl fmt::Display for UUID {
212 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
213 write!(
214 fmt,
215 "{:02x}{:02x}{:02x}{:02x}
216 {:02x}{:02x}
217 {:02x}{:02x}
218 {:02x}{:02x}
219 {:02x}{:02x}{:02x}{:02x}{:02x}{:02x}",
220 self.0[0],
221 self.0[1],
222 self.0[2],
223 self.0[3],
224 self.0[4],
225 self.0[5],
226 self.0[6],
227 self.0[7],
228 self.0[8],
229 self.0[9],
230 self.0[10],
231 self.0[11],
232 self.0[12],
233 self.0[13],
234 self.0[14],
235 self.0[15],
236 )
237 }
238}
239
240impl fmt::LowerHex for UUID {
241 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
242 write!(
243 fmt,
244 "{:02x}{:02x}{:02x}{:02x}
245 -{:02x}{:02x}
246 -{:02x}{:02x}
247 -{:02x}{:02x}
248 -{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}",
249 self.0[0],
250 self.0[1],
251 self.0[2],
252 self.0[3],
253 self.0[4],
254 self.0[5],
255 self.0[6],
256 self.0[7],
257 self.0[8],
258 self.0[9],
259 self.0[10],
260 self.0[11],
261 self.0[12],
262 self.0[13],
263 self.0[14],
264 self.0[15],
265 )
266 }
267}
268
269impl fmt::UpperExp for UUID {
270 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
271 write!(
272 fmt,
273 "{:02X}{:02X}{:02X}{:02X}
274 -{:02X}{:02X}
275 -{:02X}{:02X}
276 -{:02X}{:02X}
277 -{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}",
278 self.0[0],
279 self.0[1],
280 self.0[2],
281 self.0[3],
282 self.0[4],
283 self.0[5],
284 self.0[6],
285 self.0[7],
286 self.0[8],
287 self.0[9],
288 self.0[10],
289 self.0[11],
290 self.0[12],
291 self.0[13],
292 self.0[14],
293 self.0[15],
294 )
295 }
296}
297
298pub struct ClockSeq(u16);
301
302impl ClockSeq {
303 pub fn new(r: u16) -> u16 {
305 atomic::AtomicU16::new(r).fetch_add(1, atomic::Ordering::AcqRel)
306 }
307}
308
309pub struct Node([u8; 6]);
312
313impl fmt::Display for Node {
314 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
315 write!(
316 fmt,
317 "{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}",
318 self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5],
319 )
320 }
321}
322
323impl fmt::LowerHex for Node {
324 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
325 write!(
326 fmt,
327 "{:02x}-{:02x}-{:02x}-{:02x}-{:02x}-{:02x}",
328 self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5],
329 )
330 }
331}
332
333impl fmt::UpperHex for Node {
334 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
335 write!(
336 fmt,
337 "{:02X}-{:02X}-{:02X}-{:02X}-{:02X}-{:02X}",
338 self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5],
339 )
340 }
341}