#[allow(unused_imports)]
use alloc::string::ToString;
use crate::mesh;
use core::fmt::{Display, Error, Formatter};
type UUIDBytes = [u8; 16];
#[cfg_attr(feature = "serde-1", derive(serde::Serialize, serde::Deserialize))]
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Default)]
pub struct UUID(pub UUIDBytes);
impl UUID {
#[must_use]
pub fn from_fields(
time_low: u32,
time_mid: u16,
time_high: u16,
clock_seq: u16,
node: u64,
) -> UUID {
let tl = time_low.to_le_bytes();
let tm = time_mid.to_le_bytes();
let th = time_high.to_le_bytes();
let cs = clock_seq.to_le_bytes();
let nb = node.to_le_bytes();
UUID([
tl[0], tl[1], tl[2], tl[3], tm[0], tm[1], th[0], th[1], cs[0], cs[1], nb[0], nb[1],
nb[2], nb[3], nb[4], nb[5],
])
}
#[must_use]
pub fn time_low(&self) -> u32 {
u32::from_le_bytes([self.0[0], self.0[1], self.0[2], self.0[3]])
}
#[must_use]
pub fn time_mid(&self) -> u16 {
u16::from_le_bytes([self.0[4], self.0[5]])
}
#[must_use]
pub fn time_high(&self) -> u16 {
u16::from_le_bytes([self.0[6], self.0[7]])
}
#[must_use]
pub fn clock_seq(&self) -> u16 {
u16::from_le_bytes([self.0[8], self.0[9]])
}
#[must_use]
pub fn node(&self) -> u64 {
u64::from_le_bytes([
self.0[10], self.0[11], self.0[12], self.0[13], self.0[14], self.0[15], 0, 0,
])
}
#[must_use]
pub fn uuid_bytes_from_str(s: &str) -> Option<UUIDBytes> {
Some(mesh::bytes_str_to_buf(s)?)
}
}
impl AsRef<[u8]> for UUID {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
impl AsMut<[u8]> for UUID {
fn as_mut(&mut self) -> &mut [u8] {
&mut self.0
}
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub struct UUIDFields {
pub time_low: u32,
pub time_mid: u16,
pub time_high: u16,
pub clock_seq: u16,
pub node: u64,
}
impl Into<UUIDFields> for &UUID {
#[must_use]
fn into(self) -> UUIDFields {
UUIDFields {
time_low: self.time_low(),
time_mid: self.time_mid(),
time_high: self.time_high(),
clock_seq: self.clock_seq(),
node: self.node(),
}
}
}
impl Into<UUIDFields> for UUID {
fn into(self) -> UUIDFields {
(&self).into()
}
}
impl Into<UUID> for &UUIDFields {
#[must_use]
fn into(self) -> UUID {
UUID::from_fields(
self.time_low,
self.time_mid,
self.time_high,
self.clock_seq,
self.node,
)
}
}
impl Into<UUID> for UUIDFields {
#[must_use]
fn into(self) -> UUID {
(&self).into()
}
}
impl Display for UUID {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
write!(
f,
"{:08x}-{:04x}-{:04x}-{:04x}-{:012x}",
self.time_low(),
self.time_mid(),
self.time_high(),
self.clock_seq(),
self.node()
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_format() {
let time_low = 0x123e4567;
let time_mid = 0xe89b;
let time_high = 0x12d3;
let clock_seq = 0xa456;
let node = 0x426655440000;
let uuid = UUID::from_fields(time_low, time_mid, time_high, clock_seq, node);
let fields: UUIDFields = uuid.into();
assert_eq!(time_low, fields.time_low);
assert_eq!(time_mid, fields.time_mid);
assert_eq!(time_high, fields.time_high);
assert_eq!(clock_seq, fields.clock_seq);
assert_eq!(node, fields.node);
assert_eq!(uuid.to_string(), "123e4567-e89b-12d3-a456-426655440000");
}
}