use core::error;
use core::result;
pub struct Uuid([u8; 16]);
#[macro_export]
macro_rules! uuid {
($uuid:expr) => {{
const OUTPUT: $crate::Uuid = match $crate::Uuid::try_parse($uuid) {
$crate::__macro_support::Ok(u) => u,
$crate::__macro_support::Err(_) => panic!("invalid UUID"),
};
OUTPUT
}};
}
impl Uuid {
pub const fn as_u128(&self) -> u128 {
u128::from_be_bytes(*self.as_bytes())
}
#[inline]
pub const fn as_bytes(&self) -> &[u8; 16] {
&self.0
}
#[inline]
pub const fn into_bytes(self) -> [u8; 16] {
self.0
}
pub fn parse_str(input: &str) -> Result<Uuid, u8> {
try_parse(input.as_bytes())
.map(Uuid::from_bytes)
.map_err(|_|1)
}
#[inline]
pub const fn from_bytes(bytes: [u8; 16]) -> Uuid {
Uuid(bytes)
}
#[inline]
pub const fn from_u128(number: u128) -> Uuid {
Uuid(u128::to_be_bytes(number))
}
pub fn to_string(&self) -> alloc::string::String {
return alloc::string::String::from("Todo");
}
}
const fn try_parse(input: &'_ [u8]) -> Result<[u8; 16], u8> {
match (input.len(), input) {
(32, s) => parse_simple(s, true),
(36, s)
| (38, [b'{', s @ .., b'}'])
| (45, [b'u', b'r', b'n', b':', b'u', b'u', b'i', b'd', b':', s @ ..]) => {
parse_hyphenated(s)
}
_ => Err(1),
}
}
#[inline]
#[allow(dead_code)]
pub(crate) const fn parse_braced(input: &'_ [u8]) -> Result<[u8; 16], u8> {
if let (38, [b'{', s @ .., b'}']) = (input.len(), input) {
parse_hyphenated(s)
} else {
Err(1)
}
}
#[inline]
#[allow(dead_code)]
pub(crate) const fn parse_urn(input: &'_ [u8]) -> Result<[u8; 16], u8> {
if let (45, [b'u', b'r', b'n', b':', b'u', b'u', b'i', b'd', b':', s @ ..]) =
(input.len(), input)
{
parse_hyphenated(s)
} else {
Err(1)
}
}
#[inline]
pub(crate) const fn parse_simple(
s: &'_ [u8],
speculative: bool,
) -> Result<[u8; 16], u8> {
if s.len() != 32 {
return Err(1);
}
let mut buf: [u8; 16] = [0; 16];
let mut i = 0;
while i < 16 {
let h1 = HEX_TABLE[s[i * 2] as usize];
let h2 = HEX_TABLE[s[i * 2 + 1] as usize];
if h1 | h2 == 0xff {
return Err(1);
}
buf[i] = SHL4_TABLE[h1 as usize] | h2;
i += 1;
}
Ok(buf)
}
#[inline]
pub(crate) const fn parse_hyphenated(s: &'_ [u8]) -> Result<[u8; 16], u8> {
if s.len() != 36 {
return Err(1);
}
match [s[8], s[13], s[18], s[23]] {
[b'-', b'-', b'-', b'-'] => {}
_ => return Err(1),
}
let positions: [u8; 8] = [0, 4, 9, 14, 19, 24, 28, 32];
let mut buf: [u8; 16] = [0; 16];
let mut j = 0;
while j < 8 {
let i = positions[j];
let h1 = HEX_TABLE[s[i as usize] as usize];
let h2 = HEX_TABLE[s[(i + 1) as usize] as usize];
let h3 = HEX_TABLE[s[(i + 2) as usize] as usize];
let h4 = HEX_TABLE[s[(i + 3) as usize] as usize];
if h1 | h2 | h3 | h4 == 0xff {
return Err(1);
}
buf[j * 2] = SHL4_TABLE[h1 as usize] | h2;
buf[j * 2 + 1] = SHL4_TABLE[h3 as usize] | h4;
j += 1;
}
Ok(buf)
}
const HEX_TABLE: &[u8; 256] = &{
let mut buf = [0; 256];
let mut i: u8 = 0;
loop {
buf[i as usize] = match i {
b'0'..=b'9' => i - b'0',
b'a'..=b'f' => i - b'a' + 10,
b'A'..=b'F' => i - b'A' + 10,
_ => 0xff,
};
if i == 255 {
break buf;
}
i += 1
}
};
const SHL4_TABLE: &[u8; 256] = &{
let mut buf = [0; 256];
let mut i: u8 = 0;
loop {
buf[i as usize] = i.wrapping_shl(4);
if i == 255 {
break buf;
}
i += 1;
}
};
impl Clone for Uuid {
fn clone(&self) -> Self {
Uuid::from_u128(self.as_u128())
}
}
impl Copy for Uuid {
}