#![doc(html_root_url = "https://docs.rs/uuid-rs")]
mod name;
mod rand;
mod time;
use core::fmt;
use core::sync::atomic;
use std::time::SystemTime;
pub const UTC_EPOCH: u64 = 0x1B21_DD21_3814_000;
#[derive(Debug)]
pub struct Layout {
pub field_low: u32,
pub field_mid: u16,
pub field_high_and_version: u16,
pub clock_seq_high_and_reserved: u8,
pub clock_seq_low: u8,
pub node: [u8; 6],
}
impl Layout {
pub fn as_fields(&self) -> (u32, u16, u16, u16, u64) {
(
self.field_low,
self.field_mid,
self.field_high_and_version,
((self.clock_seq_high_and_reserved as u16) << 8) | self.clock_seq_low as u16,
(self.node[0] as u64) << 40
| (self.node[1] as u64) << 32
| (self.node[2] as u64) << 24
| (self.node[3] as u64) << 16
| (self.node[4] as u64) << 8
| (self.node[5] as u64),
)
}
pub fn as_bytes(&self) -> UUID {
UUID([
self.field_low.to_be_bytes()[0],
self.field_low.to_be_bytes()[1],
self.field_low.to_be_bytes()[2],
self.field_low.to_be_bytes()[3],
self.field_mid.to_be_bytes()[0],
self.field_mid.to_be_bytes()[1],
self.field_high_and_version.to_be_bytes()[0],
self.field_high_and_version.to_be_bytes()[1],
self.clock_seq_high_and_reserved,
self.clock_seq_low,
self.node[0],
self.node[1],
self.node[2],
self.node[3],
self.node[4],
self.node[5],
])
}
pub fn get_version(&self) -> Option<Version> {
match (self.field_high_and_version >> 12) & 0xf {
0x01 => Some(Version::TIME),
0x02 => Some(Version::DCE),
0x03 => Some(Version::MD5),
0x04 => Some(Version::RAND),
0x05 => Some(Version::SHA1),
_ => None,
}
}
pub fn get_variant(&self) -> Option<Variant> {
match (self.clock_seq_high_and_reserved >> 4) & 0xf {
0x00 => Some(Variant::NCS),
0x01 => Some(Variant::RFC),
0x02 => Some(Variant::MS),
0x03 => Some(Variant::FUT),
_ => None,
}
}
pub fn get_time(&self) -> u64 {
self.field_low as u64
}
pub fn get_mac(&self) -> Node {
Node(self.node)
}
}
#[derive(Debug, Copy, Clone)]
pub enum Domain {
PERSON = 0,
GROUP,
ORG,
}
#[derive(Debug, Eq, PartialEq)]
pub enum Variant {
NCS = 0,
RFC,
MS,
FUT,
}
#[derive(Debug, Eq, PartialEq)]
pub enum Version {
TIME = 1,
DCE,
MD5,
RAND,
SHA1,
}
#[derive(Debug, Eq, PartialEq)]
pub struct Timestamp(u64);
impl Timestamp {
pub fn new() -> u64 {
let utc = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.checked_add(std::time::Duration::from_nanos(UTC_EPOCH))
.unwrap()
.as_nanos();
(utc & 0xffff_ffff_ffff_ffff) as u64
}
}
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub struct UUID([u8; 16]);
impl UUID {
pub const NIL: Self = UUID([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
pub const NAMESPACE_DNS: Self = UUID([
0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30,
0xc8,
]);
pub const NAMESPACE_OID: Self = UUID([
0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30,
0xc8,
]);
pub const NAMESPACE_URL: Self = UUID([
0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30,
0xc8,
]);
pub const NAMESPACE_X500: Self = UUID([
0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30,
0xc8,
]);
}
impl fmt::Display for UUID {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
fmt,
"{:02x}{:02x}{:02x}{:02x}
{:02x}{:02x}
{:02x}{:02x}
{:02x}{:02x}
{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}",
self.0[0],
self.0[1],
self.0[2],
self.0[3],
self.0[4],
self.0[5],
self.0[6],
self.0[7],
self.0[8],
self.0[9],
self.0[10],
self.0[11],
self.0[12],
self.0[13],
self.0[14],
self.0[15],
)
}
}
impl fmt::LowerHex for UUID {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
fmt,
"{:02x}{:02x}{:02x}{:02x}
-{:02x}{:02x}
-{:02x}{:02x}
-{:02x}{:02x}
-{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}",
self.0[0],
self.0[1],
self.0[2],
self.0[3],
self.0[4],
self.0[5],
self.0[6],
self.0[7],
self.0[8],
self.0[9],
self.0[10],
self.0[11],
self.0[12],
self.0[13],
self.0[14],
self.0[15],
)
}
}
impl fmt::UpperExp for UUID {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
fmt,
"{:02X}{:02X}{:02X}{:02X}
-{:02X}{:02X}
-{:02X}{:02X}
-{:02X}{:02X}
-{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}",
self.0[0],
self.0[1],
self.0[2],
self.0[3],
self.0[4],
self.0[5],
self.0[6],
self.0[7],
self.0[8],
self.0[9],
self.0[10],
self.0[11],
self.0[12],
self.0[13],
self.0[14],
self.0[15],
)
}
}
pub struct ClockSeq(u16);
impl ClockSeq {
pub fn new(r: u16) -> u16 {
atomic::AtomicU16::new(r).fetch_add(1, atomic::Ordering::AcqRel)
}
}
pub struct Node([u8; 6]);
impl fmt::Display for Node {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
fmt,
"{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}",
self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5],
)
}
}
impl fmt::LowerHex for Node {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
fmt,
"{:02x}-{:02x}-{:02x}-{:02x}-{:02x}-{:02x}",
self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5],
)
}
}
impl fmt::UpperHex for Node {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
fmt,
"{:02X}-{:02X}-{:02X}-{:02X}-{:02X}-{:02X}",
self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5],
)
}
}