#![cfg_attr(not(any(test, feature = "std")), no_std)]
#![cfg_attr(docsrs, feature(doc_cfg))]
use core::{
convert::TryInto,
fmt,
str::{from_utf8_unchecked_mut, FromStr},
};
use hex_simd::{decode_inplace, AsciiCase::Lower, Out};
use md5::{Digest, Md5};
#[cfg(feature = "getrandom")]
use rand_chacha::rand_core::OsRng;
use rand_chacha::{
rand_core::{RngCore, SeedableRng},
ChaChaRng,
};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use sha1::Sha1;
const UUID_STR_LENGTH: usize = 36;
const UUID_URN_LENGTH: usize = 45;
const UUID_BRACED_LENGTH: usize = 38;
const UUID_SIMPLE_LENGTH: usize = 32;
const UUID_URN: &str = "urn:uuid:";
const UUID_URN_PREFIX: usize = UUID_URN.len();
pub const NAMESPACE_DNS: Uuid = Uuid::from_bytes([
107, 167, 184, 16, 157, 173, 17, 209, 128, 180, 0, 192, 79, 212, 48, 200,
]);
pub const NAMESPACE_URL: Uuid = Uuid::from_bytes([
107, 167, 184, 17, 157, 173, 17, 209, 128, 180, 0, 192, 79, 212, 48, 200,
]);
pub const NAMESPACE_OID: Uuid = Uuid::from_bytes([
107, 167, 184, 18, 157, 173, 17, 209, 128, 180, 0, 192, 79, 212, 48, 200,
]);
pub const NAMESPACE_X500: Uuid = Uuid::from_bytes([
107, 167, 184, 20, 157, 173, 17, 209, 128, 180, 0, 192, 79, 212, 48, 200,
]);
pub type Bytes = [u8; 16];
#[derive(Debug, Clone)]
pub struct Rng(ChaChaRng);
impl Rng {
#[cfg(feature = "getrandom")]
#[cfg_attr(docsrs, doc(cfg(feature = "getrandom")))]
#[inline]
pub fn new() -> Self {
Self(ChaChaRng::from_rng(OsRng).unwrap())
}
#[inline]
pub fn from_seed(seed: [u8; 32]) -> Self {
Self(ChaChaRng::from_seed(seed))
}
#[inline]
fn fill_bytes(&mut self, dest: &mut [u8]) {
self.0.fill_bytes(dest)
}
}
#[cfg_attr(docsrs, doc(cfg(feature = "getrandom")))]
#[cfg(feature = "getrandom")]
impl Default for Rng {
#[inline]
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
#[non_exhaustive]
pub enum Variant {
Ncs,
Rfc4122,
Microsoft,
Reserved,
}
impl fmt::Display for Variant {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Variant::Ncs => write!(f, "Ncs"),
Variant::Rfc4122 => write!(f, "Rfc4122"),
Variant::Microsoft => write!(f, "Microsoft"),
Variant::Reserved => write!(f, "Reserved"),
}
}
}
#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
#[non_exhaustive]
pub enum Version {
Nil = 0,
Time,
Dce,
Md5,
Random,
Sha1,
#[cfg(feature = "experimental_uuid")]
#[cfg_attr(docsrs, doc(cfg(feature = "experimental_uuid")))]
Database,
#[cfg(feature = "experimental_uuid")]
#[cfg_attr(docsrs, doc(cfg(feature = "experimental_uuid")))]
UnixTime,
#[cfg(feature = "experimental_uuid")]
#[cfg_attr(docsrs, doc(cfg(feature = "experimental_uuid")))]
Vendor,
Reserved,
}
impl fmt::Display for Version {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Version::Nil => write!(f, "Nil"),
Version::Time => write!(f, "Time"),
Version::Dce => write!(f, "Dce"),
Version::Md5 => write!(f, "Md5"),
Version::Random => write!(f, "Random"),
Version::Sha1 => write!(f, "Sha1"),
#[cfg(feature = "experimental_uuid")]
Version::Database => write!(f, "Database"),
#[cfg(feature = "experimental_uuid")]
Version::UnixTime => write!(f, "UnixTime"),
#[cfg(feature = "experimental_uuid")]
Version::Vendor => write!(f, "Vendor"),
Version::Reserved => write!(f, "Reserved"),
}
}
}
#[derive(Debug)]
pub struct ParseUuidError;
impl fmt::Display for ParseUuidError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "ParseUuidError")
}
}
#[cfg(any(test, feature = "std"))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl std::error::Error for ParseUuidError {}
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Default)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(transparent))]
#[repr(transparent)]
pub struct Uuid(Bytes);
impl Uuid {
#[inline]
fn set_version(&mut self, ver: Version) {
self.0[6] = (self.0[6] & 0xF) | ((ver as u8) << 4);
}
#[inline]
fn set_variant(&mut self, ver: Variant) {
let byte = self.0[8];
self.0[8] = match ver {
Variant::Ncs => byte & 0x7F,
Variant::Rfc4122 => (byte & 0x3F) | 0x80,
Variant::Microsoft => (byte & 0x1F) | 0xC0,
Variant::Reserved => byte | 0xE0,
}
}
#[inline]
const fn swap_endian(mut self) -> Self {
let (a1, a2, a3, a4) = (self.0[0], self.0[1], self.0[2], self.0[3]);
self.0[0] = a4;
self.0[1] = a3;
self.0[2] = a2;
self.0[3] = a1;
let (a1, a2) = (self.0[4], self.0[5]);
self.0[4] = a2;
self.0[5] = a1;
let (a1, a2) = (self.0[6], self.0[7]);
self.0[6] = a2;
self.0[7] = a1;
self
}
}
impl Uuid {
#[inline]
pub const fn nil() -> Self {
Uuid([0; 16])
}
#[inline]
#[cfg(feature = "experimental_uuid")]
#[cfg_attr(docsrs, doc(cfg(feature = "experimental_uuid")))]
pub const fn max() -> Self {
Uuid([1; 16])
}
#[inline]
pub const fn from_bytes(bytes: Bytes) -> Self {
Self(bytes)
}
#[inline]
pub const fn to_bytes(self) -> Bytes {
self.0
}
#[inline]
pub const fn from_bytes_me(bytes: Bytes) -> Self {
Self(bytes).swap_endian()
}
#[inline]
pub const fn to_bytes_me(self) -> Bytes {
self.swap_endian().to_bytes()
}
#[inline]
pub const fn is_nil(self) -> bool {
u128::from_ne_bytes(self.0) == 0
}
#[inline]
pub const fn variant(self) -> Variant {
let byte = (self.0[8] >> 5) & 0b111;
match (
byte >> 2 & 1 == 1,
byte >> 1 & 1 == 1,
byte & 1 == 1,
) {
(false, ..) => Variant::Ncs,
(true, false, ..) => Variant::Rfc4122,
(true, true, false) => Variant::Microsoft,
(true, true, true) => Variant::Reserved,
}
}
#[inline]
pub const fn version(self) -> Version {
match (
self.0[6] >> 7 & 1 == 1,
self.0[6] >> 6 & 1 == 1,
self.0[6] >> 5 & 1 == 1,
self.0[6] >> 4 & 1 == 1,
) {
(false, false, false, false) => Version::Nil,
(false, false, false, true) => Version::Time,
(false, false, true, false) => Version::Dce,
(false, false, true, true) => Version::Md5,
(false, true, false, false) => Version::Random,
(false, true, false, true) => Version::Sha1,
#[cfg(feature = "experimental_uuid")]
(false, true, true, false) => Version::Database,
#[cfg(feature = "experimental_uuid")]
(false, true, true, true) => Version::UnixTime,
#[cfg(feature = "experimental_uuid")]
(true, false, false, false) => Version::Vendor,
_ => Version::Reserved,
}
}
#[inline]
pub const fn timestamp(self) -> u64 {
match self.version() {
#[cfg(feature = "experimental_uuid")]
Version::Database => u64::from_be_bytes([
self.0[6] & 0xF,
self.0[7],
self.0[4],
self.0[5],
self.0[0],
self.0[1],
self.0[2],
self.0[3],
]),
_ => u64::from_be_bytes([
self.0[6] & 0xF,
self.0[7],
self.0[4],
self.0[5],
self.0[0],
self.0[1],
self.0[2],
self.0[3],
]),
}
}
#[inline]
pub const fn clock_sequence(self) -> u16 {
u16::from_be_bytes([
self.0[8] & 0x3F,
self.0[9],
])
}
#[inline]
pub const fn node(self) -> [u8; 6] {
[
self.0[10], self.0[11], self.0[12], self.0[13], self.0[14], self.0[15],
]
}
pub fn to_str(self, buf: &mut [u8; 36]) -> &mut str {
buf[8] = b'-';
buf[13] = b'-';
buf[18] = b'-';
buf[23] = b'-';
let bytes = self.to_bytes();
let time_low = &bytes[..4];
let time_mid = &bytes[4..6];
let time_hi_and_version = &bytes[6..8];
let clock_seq_hi_and_reserved = &bytes[8..9];
let clock_seq_low = &bytes[9..10];
let node = &bytes[10..];
let _ = hex_simd::encode(time_low, Out::from_slice(&mut buf[..8]), Lower);
let _ = hex_simd::encode(time_mid, Out::from_slice(&mut buf[9..13]), Lower);
let _ = hex_simd::encode(
time_hi_and_version,
Out::from_slice(&mut buf[14..18]),
Lower,
);
let _ = hex_simd::encode(
clock_seq_hi_and_reserved,
Out::from_slice(&mut buf[19..21]),
Lower,
);
let _ = hex_simd::encode(clock_seq_low, Out::from_slice(&mut buf[21..23]), Lower);
let _ = hex_simd::encode(node, Out::from_slice(&mut buf[24..]), Lower);
debug_assert!(buf.is_ascii(), "BUG: Invalid ASCII in nuuid::Uuid::to_str");
unsafe { from_utf8_unchecked_mut(buf) }
}
#[inline]
pub fn to_urn(self, buf: &mut [u8; 45]) -> &mut str {
buf[..UUID_URN_PREFIX].copy_from_slice(UUID_URN.as_bytes());
self.to_str((&mut buf[UUID_URN_PREFIX..]).try_into().unwrap());
core::str::from_utf8_mut(buf).expect("BUG: Invalid UTF8")
}
#[inline]
pub fn to_str_upper(self, buf: &mut [u8; 36]) -> &mut str {
let s = self.to_str(buf);
s.make_ascii_uppercase();
s
}
#[inline]
pub fn to_urn_upper(self, buf: &mut [u8; 45]) -> &mut str {
let s = self.to_urn(buf);
s[UUID_URN_PREFIX..].make_ascii_uppercase();
s
}
}
impl Uuid {
pub fn parse(s: &str) -> Result<Self, ParseUuidError> {
if !s.is_ascii() {
return Err(ParseUuidError);
}
let s = match s.len() {
UUID_URN_LENGTH => &s[UUID_URN_PREFIX..],
UUID_BRACED_LENGTH => &s[1..s.len() - 1],
UUID_STR_LENGTH => s,
UUID_SIMPLE_LENGTH => {
return Ok(Uuid::from_bytes(
u128::from_str_radix(s, 16)
.map_err(|_| ParseUuidError)?
.to_be_bytes(),
));
}
_ => return Err(ParseUuidError),
};
let s = s.as_bytes();
let mut raw = [0; UUID_SIMPLE_LENGTH];
raw[20..].copy_from_slice(&s[24..]);
raw[16..20].copy_from_slice(&s[19..23]);
raw[12..16].copy_from_slice(&s[14..18]);
raw[8..12].copy_from_slice(&s[9..13]);
raw[..8].copy_from_slice(&s[..8]);
let x = decode_inplace(&mut raw).map_err(|_| ParseUuidError)?;
Ok(Uuid::from_bytes(x.try_into().map_err(|_| ParseUuidError)?))
}
pub fn parse_me(s: &str) -> Result<Self, ParseUuidError> {
Uuid::from_str(s).map(Uuid::swap_endian)
}
#[cfg(feature = "getrandom")]
#[cfg_attr(docsrs, doc(cfg(feature = "getrandom")))]
#[inline]
pub fn new_v4() -> Self {
let mut uuid = Uuid::nil();
OsRng.fill_bytes(&mut uuid.0);
uuid.set_variant(Variant::Rfc4122);
uuid.set_version(Version::Random);
uuid
}
#[inline]
pub fn new_v4_rng(rng: &mut Rng) -> Self {
let mut uuid = Uuid::nil();
rng.fill_bytes(&mut uuid.0);
uuid.set_variant(Variant::Rfc4122);
uuid.set_version(Version::Random);
uuid
}
#[inline]
pub fn new_v3(namespace: Uuid, name: &[u8]) -> Self {
let mut hasher = Md5::new();
hasher.update(namespace.to_bytes());
hasher.update(name);
let mut uuid = Uuid::from_bytes(hasher.finalize().into());
uuid.set_version(Version::Md5);
uuid.set_variant(Variant::Rfc4122);
uuid
}
#[inline]
pub fn new_v5(namespace: Uuid, name: &[u8]) -> Self {
let mut hasher = Sha1::new();
hasher.update(namespace.to_bytes());
hasher.update(name);
let mut uuid = Uuid::from_bytes(hasher.finalize()[..16].try_into().unwrap());
uuid.set_version(Version::Sha1);
uuid.set_variant(Variant::Rfc4122);
uuid
}
#[inline]
pub fn new_v1(timestamp: u64, counter: u16, node: [u8; 6]) -> Self {
let timestamp = timestamp.to_be_bytes();
let counter = counter.to_be_bytes();
Uuid::from_bytes([
timestamp[4],
timestamp[5],
timestamp[6],
timestamp[7],
timestamp[2],
timestamp[3],
(timestamp[0] & 0xF) | (1u8 << 4),
timestamp[1],
(counter[0] & 0x3F) | 0x80,
counter[1],
node[0],
node[1],
node[2],
node[3],
node[4],
node[5],
])
}
#[inline]
#[cfg(feature = "experimental_uuid")]
#[cfg_attr(docsrs, doc(cfg(feature = "experimental_uuid")))]
pub fn new_v6(timestamp: u64, counter: u16, node: [u8; 6]) -> Self {
let timestamp = (timestamp << 4).to_be_bytes();
let counter = counter.to_be_bytes();
Uuid::from_bytes([
timestamp[0],
timestamp[1],
timestamp[2],
timestamp[3],
timestamp[4],
timestamp[5],
(timestamp[6] >> 4) | (6u8 << 4),
timestamp[7],
(counter[0] & 0x3F) | 0x80,
counter[1],
node[0],
node[1],
node[2],
node[3],
node[4],
node[5],
])
}
#[inline]
#[cfg(feature = "experimental_uuid")]
#[cfg_attr(docsrs, doc(cfg(feature = "experimental_uuid")))]
pub fn new_v7(timestamp: u64, rand_a: u16, rand_b: u64) -> Self {
let timestamp = (timestamp << 16).to_be_bytes();
let rand_a = rand_a.to_be_bytes();
let rand_b = rand_b.to_be_bytes();
Uuid::from_bytes([
timestamp[0],
timestamp[1],
timestamp[2],
timestamp[3],
timestamp[4],
timestamp[5],
(rand_a[0] & 0xF) | (7u8 << 4),
rand_a[1],
(rand_b[0] & 0x3F) | 0x80,
rand_b[1],
rand_b[2],
rand_b[3],
rand_b[4],
rand_b[5],
rand_b[6],
rand_b[7],
])
}
#[inline]
#[cfg(feature = "experimental_uuid")]
#[cfg_attr(docsrs, doc(cfg(feature = "experimental_uuid")))]
pub fn new_v8(bytes: Bytes) -> Self {
let mut uuid = Uuid::from_bytes(bytes);
uuid.set_variant(Variant::Rfc4122);
uuid.set_version(Version::Vendor);
uuid
}
}
impl FromStr for Uuid {
type Err = ParseUuidError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Uuid::parse(s)
}
}
impl fmt::Display for Uuid {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:X}", self)
}
}
impl fmt::Debug for Uuid {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if f.alternate() {
write!(
f,
r#"Uuid({:X}) {{
Version: {}({}),
Variant: {}({}),
}}"#,
self,
self.version(),
self.version() as u8,
self.variant(),
self.variant() as u8
)
} else {
write!(f, "Uuid({:X})", self)
}
}
}
impl fmt::LowerHex for Uuid {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if f.alternate() {
write!(f, "{}", UUID_URN)?;
}
let mut buf = [0; 36];
let s = self.to_str(&mut buf);
write!(f, "{}", s)
}
}
impl fmt::UpperHex for Uuid {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if f.alternate() {
write!(f, "{}", UUID_URN)?;
}
let mut buf = [0; 36];
write!(f, "{}", self.to_str_upper(&mut buf))
}
}
impl AsRef<[u8]> for Uuid {
#[inline]
fn as_ref(&self) -> &[u8] {
&self.0
}
}
impl AsRef<[u8; 16]> for Uuid {
#[inline]
fn as_ref(&self) -> &[u8; 16] {
&self.0
}
}
#[cfg(test)]
mod tests {
use super::*;
const UUID_NIL: &str = "00000000-0000-0000-0000-000000000000";
const UUID_V4: &str = "662aa7c7-7598-4d56-8bcc-a72c30f998a2";
const UUID_V4_SIMPLE: &str = "662aa7c775984d568bcca72c30f998a2";
const UUID_V4_BRACED: &str = "{662aa7c7-7598-4d56-8bcc-a72c30f998a2}";
const UUID_V4_URN: &str = "urn:uuid:662aa7c7-7598-4d56-8bcc-a72c30f998a2";
const UUID_V4_URN_UPPER: &str = "urn:uuid:662AA7C7-7598-4D56-8BCC-A72C30F998A2";
const RAW: [u8; 16] = [
102, 42, 167, 199, 117, 152, 77, 86, 139, 204, 167, 44, 48, 249, 152, 162,
];
fn name(fun: fn(Uuid, &[u8]) -> Uuid, ver: Version) {
let namespace = Uuid::new_v4();
let namespace2 = Uuid::new_v4();
let uuid1 = fun(namespace, b"test");
let uuid2 = fun(namespace, b"test");
assert_eq!(
uuid1, uuid2,
"UUID's from different times with the same name/namespace must be equal"
);
let uuid = fun(namespace, b"Cat");
assert_ne!(
uuid, uuid2,
"UUID's with two different names in the same namespace must NOT be equal"
);
let uuid = fun(namespace2, b"test");
assert_ne!(
uuid, uuid2,
"UUID's with the same names in a different namespace must NOT be equal"
);
assert_eq!(uuid.version(), ver);
assert_eq!(uuid.variant(), Variant::Rfc4122);
}
#[test]
#[cfg(feature = "experimental_uuid")]
fn new_v6() {
const UUID: &str = "1EC9414C-232A-6B00-B3C8-9E6BDECED846";
let (ticks, counter, node) = (138648505420000000, 13256, [158, 107, 222, 206, 216, 70]);
let uuid = Uuid::new_v6(ticks, counter, node);
let uuid_ = Uuid::parse(UUID).unwrap();
assert_eq!(uuid.to_str_upper(&mut [0; 36]), UUID);
assert_eq!(uuid.version(), Version::Database);
assert_eq!(uuid.variant(), Variant::Rfc4122);
assert_eq!(uuid.timestamp(), uuid_.timestamp());
assert_eq!(uuid.clock_sequence(), uuid_.clock_sequence());
assert_eq!(uuid.node()[..], uuid_.node());
}
#[test]
#[cfg(feature = "experimental_uuid")]
fn new_v7() {
const UUID: &str = "017F22E2-79B0-7CC3-98C4-DC0C0C07398F";
let (unix_ts, rand_a, rand_b) = (0x17F22E279B0, 0xCC3, 0x18C4DC0C0C07398F);
let uuid = Uuid::new_v7(unix_ts, rand_a, rand_b);
let uuid_ = Uuid::parse(UUID).unwrap();
assert_eq!(uuid.to_str_upper(&mut [0; 36]), UUID);
assert_eq!(uuid.version(), Version::UnixTime);
assert_eq!(uuid.variant(), Variant::Rfc4122);
assert_eq!(uuid.timestamp(), uuid_.timestamp());
assert_eq!(uuid.clock_sequence(), uuid_.clock_sequence());
assert_eq!(uuid.node()[..], uuid_.node());
}
#[test]
fn time() {
use uuid_::{v1::*, Uuid as Uuid_};
let (ticks, counter, node) = (138788330336896890u64, 8648, *b"world!");
let uuid = Uuid::new_v1(ticks, counter, node);
let uuid_ = Uuid_::new_v1(Timestamp::from_rfc4122(ticks, counter), &node);
assert_eq!(uuid.to_bytes(), *uuid_.as_bytes());
assert_eq!(uuid.version(), Version::Time);
assert_eq!(uuid.variant(), Variant::Rfc4122);
assert_eq!(
uuid.timestamp(),
uuid_.get_timestamp().unwrap().to_rfc4122().0
);
assert_eq!(
uuid.clock_sequence(),
uuid_.get_timestamp().unwrap().to_rfc4122().1
);
assert_eq!(uuid.node()[..], uuid_.as_fields().3[2..]);
}
#[test]
fn md5() {
name(Uuid::new_v3, Version::Md5);
let uuid = Uuid::new_v3(NAMESPACE_DNS, b"www.widgets.com");
assert_eq!(
uuid,
Uuid::from_str("3d813cbb-47fb-32ba-91df-831e1593ac29").unwrap()
)
}
#[test]
fn sha1() {
name(Uuid::new_v5, Version::Sha1)
}
#[test]
fn parse_string() {
let test = &[UUID_V4, UUID_V4_URN, UUID_V4_BRACED, UUID_V4_SIMPLE];
for uuid in test {
println!("Source UUID: {}", uuid);
let uuid = Uuid::from_str(&uuid.to_ascii_lowercase()).unwrap();
println!("Parsed UUID: {}\n", uuid);
assert_eq!(RAW, uuid.to_bytes(), "Parsed UUID bytes don't match");
}
for uuid in test {
println!("Source UUID: {}", uuid);
let uuid = Uuid::from_str(&uuid.to_ascii_uppercase()).unwrap();
println!("Parsed UUID: {}\n", uuid);
assert_eq!(RAW, uuid.to_bytes(), "Parsed UUID bytes don't match");
}
}
#[test]
fn string() {
let uuid = Uuid::from_bytes(RAW);
let mut buf = [0; 45];
assert_eq!(
uuid.to_str((&mut buf[..36]).try_into().unwrap()),
UUID_V4,
"UUID strings didn't match"
);
assert_eq!(
uuid.to_urn(&mut buf),
UUID_V4_URN,
"UUID URN strings didn't match"
);
assert_eq!(
uuid.to_urn_upper(&mut buf),
UUID_V4_URN_UPPER,
"UUID URN upper strings didn't match"
);
assert_eq!(
format!("{:#x}", uuid),
UUID_V4_URN,
"UUID URN Display didn't match"
);
assert_eq!(format!("{:x}", uuid), UUID_V4, "UUID Display didn't match");
assert_eq!(
format!("{}", uuid),
UUID_V4.to_ascii_uppercase(),
"UUID Display didn't match"
);
assert_eq!(
format!("{}", Uuid::nil()),
UUID_NIL,
"Nil UUID Display didn't work!"
);
}
#[test]
fn endian() {
let uuid_be = Uuid::from_bytes(RAW);
assert_eq!(uuid_be.version(), Version::Random);
assert_eq!(uuid_be.variant(), Variant::Rfc4122);
let uuid_le = Uuid::from_bytes_me(uuid_be.to_bytes_me());
assert_eq!(uuid_le.version(), Version::Random);
assert_eq!(uuid_le.variant(), Variant::Rfc4122);
assert_eq!(uuid_le, uuid_be);
assert_ne!(uuid_be.to_bytes_me(), uuid_be.to_bytes());
const UUID: &str = "20169084-b186-884f-b110-3db2c37eb8b5";
let uuid = Uuid::parse_me(UUID).unwrap();
let bad_uuid = Uuid::parse(UUID).unwrap();
assert_ne!(bad_uuid.version(), Version::Random);
assert_eq!(uuid.version(), Version::Random);
assert_eq!(uuid.variant(), Variant::Rfc4122);
assert_ne!(uuid.to_str(&mut [0; 36]), UUID);
}
#[test]
fn info() {
let uuid = Uuid::from_bytes(RAW);
assert_eq!(uuid.version(), Version::Random);
assert_eq!(uuid.variant(), Variant::Rfc4122);
#[cfg(feature = "getrandom")]
{
let uuid = Uuid::new_v4();
assert_eq!(uuid.version(), Version::Random);
assert_eq!(uuid.variant(), Variant::Rfc4122);
}
}
}