use std::{
fmt::Display,
time::{Duration, SystemTime},
};
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
pub struct ClientId(pub u128);
impl ClientId {
pub(crate) fn new() -> Self {
let d1 = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap_or(Duration::from_secs(1));
let d2 = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap_or(Duration::from_secs(1));
let m = d2.saturating_sub(d1).as_nanos();
let d1 = d1.as_nanos().wrapping_mul(17).wrapping_mul(m);
let d2 = d2.as_nanos().wrapping_mul(29).wrapping_mul(m);
let r = ((d1 << 64) | d2).wrapping_mul(m);
Self(r ^ d1 ^ d2)
}
pub(crate) fn from_u128(value: u128) -> Self {
Self(value)
}
pub(crate) fn as_u128(&self) -> u128 {
self.0
}
}
impl Display for ClientId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let bytes: [u8; 16] = u128::to_ne_bytes(self.0);
for b in bytes {
write!(f, "{b:02x}")?;
}
Ok(())
}
}