1use std::{
2 fmt::Display,
3 time::{Duration, SystemTime},
4};
5
6#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
7pub struct Uuid(pub u128);
8
9impl Uuid {
10 pub(crate) fn new_v4() -> Self {
11 let d1 = SystemTime::now()
12 .duration_since(SystemTime::UNIX_EPOCH)
13 .unwrap_or(Duration::from_secs(1));
14 let d2 = SystemTime::now()
15 .duration_since(SystemTime::UNIX_EPOCH)
16 .unwrap_or(Duration::from_secs(1));
17 let m = d2.saturating_sub(d1).as_nanos();
18 let d1 = d1.as_nanos().wrapping_mul(17).wrapping_mul(m);
19 let d2 = d2.as_nanos().wrapping_mul(29).wrapping_mul(m);
20 let r = ((d1 << 64) | d2).wrapping_mul(m);
21 Self(r ^ d1 ^ d2)
22 }
23
24 pub(crate) fn from_u128(value: u128) -> Self {
25 Self(value)
26 }
27
28 pub(crate) fn as_u128(&self) -> u128 {
29 self.0
30 }
31}
32
33impl Display for Uuid {
34 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35 let bytes: [u8; 16] = u128::to_ne_bytes(self.0);
36 for b in bytes {
37 write!(f, "{:02x}", b)?;
38 }
39 Ok(())
40 }
41}