use std::{
str::FromStr,
time::{SystemTime, UNIX_EPOCH},
};
use uuid::Uuid;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct ID(Uuid);
impl ID {
pub fn new() -> Self {
let now = SystemTime::now();
let since_epoch = now
.duration_since(UNIX_EPOCH)
.expect("Must be run after 1970 (large ask, I know)")
.as_secs() as u32;
let since_epoch_be = since_epoch.to_be_bytes();
let mut uuid_bytes = Uuid::new_v4().as_bytes().to_owned();
uuid_bytes[..since_epoch_be.len()].clone_from_slice(&since_epoch_be[..]);
Self(Uuid::from_bytes(uuid_bytes))
}
pub const fn null() -> Self {
Self(Uuid::nil())
}
pub const fn from_u128(x: u128) -> Self {
Self(Uuid::from_u128(x))
}
}
impl Default for ID {
fn default() -> Self {
Self::new()
}
}
impl FromStr for ID {
type Err = Box<dyn std::error::Error>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self(Uuid::from_str(s)?))
}
}
impl ToString for ID {
fn to_string(&self) -> String {
self.0.to_string()
}
}
impl From<u128> for ID {
fn from(n: u128) -> Self {
Self(Uuid::from_u128(n))
}
}
impl From<ID> for u128 {
fn from(val: ID) -> Self {
val.0.as_u128()
}
}
impl From<[u8; 16]> for ID {
fn from(bytes: [u8; 16]) -> Self {
Self(Uuid::from_bytes(bytes))
}
}
impl From<&ID> for [u8; 16] {
fn from(id: &ID) -> Self {
id.0.as_bytes().to_owned()
}
}
impl From<ID> for [u8; 16] {
fn from(id: ID) -> Self {
<[u8; 16]>::from(&id)
}
}