From 4e8199b572f2035b7749cba276ece3a26630d23e Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:18:21 +0200 Subject: Adding upstream version 1.67.1+dfsg1. Signed-off-by: Daniel Baumann --- vendor/uuid/src/lib.rs | 1070 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1070 insertions(+) create mode 100644 vendor/uuid/src/lib.rs (limited to 'vendor/uuid/src/lib.rs') diff --git a/vendor/uuid/src/lib.rs b/vendor/uuid/src/lib.rs new file mode 100644 index 000000000..51d3877f6 --- /dev/null +++ b/vendor/uuid/src/lib.rs @@ -0,0 +1,1070 @@ +// Copyright 2013-2014 The Rust Project Developers. +// Copyright 2018 The Uuid Project Developers. +// +// See the COPYRIGHT file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Generate and parse UUIDs. +//! +//! Provides support for Universally Unique Identifiers (UUIDs). A UUID is a +//! unique 128-bit number, stored as 16 octets. UUIDs are used to assign +//! unique identifiers to entities without requiring a central allocating +//! authority. +//! +//! They are particularly useful in distributed systems, though can be used in +//! disparate areas, such as databases and network protocols. Typically a UUID +//! is displayed in a readable string form as a sequence of hexadecimal digits, +//! separated into groups by hyphens. +//! +//! The uniqueness property is not strictly guaranteed, however for all +//! practical purposes, it can be assumed that an unintentional collision would +//! be extremely unlikely. +//! +//! # Dependencies +//! +//! By default, this crate depends on nothing but `std` and cannot generate +//! UUIDs. You need to enable the following Cargo features to enable +//! various pieces of functionality: +//! +//! * `v1` - adds the [`Uuid::new_v1`] function and the ability to create a V1 +//! using an implementation of [`v1::ClockSequence`] (usually +//! [`v1::Context`]) and a timestamp from `time::timespec`. +//! * `v3` - adds the [`Uuid::new_v3`] function and the ability to create a V3 +//! UUID based on the MD5 hash of some data. +//! * `v4` - adds the [`Uuid::new_v4`] function and the ability to randomly +//! generate a UUID. +//! * `v5` - adds the [`Uuid::new_v5`] function and the ability to create a V5 +//! UUID based on the SHA1 hash of some data. +//! * `serde` - adds the ability to serialize and deserialize a UUID using the +//! `serde` crate. +//! +//! For WebAssembly, enable one of the following features depending +//! on your JavaScript interop toolchain of choice: +//! +//! * `stdweb` - for [`stdweb`] combined with [`cargo-web`] +//! * `wasm-bindgen` - for [`wasm-bindgen`] +//! +//! By default, `uuid` can be depended on with: +//! +//! ```toml +//! [dependencies] +//! uuid = "0.8" +//! ``` +//! +//! To activate various features, use syntax like: +//! +//! ```toml +//! [dependencies] +//! uuid = { version = "0.8", features = ["serde", "v4"] } +//! ``` +//! +//! You can disable default features with: +//! +//! ```toml +//! [dependencies] +//! uuid = { version = "0.8", default-features = false } +//! ``` +//! +//! # Examples +//! +//! To parse a UUID given in the simple format and print it as a urn: +//! +//! ```rust +//! use uuid::Uuid; +//! +//! fn main() -> Result<(), uuid::Error> { +//! let my_uuid = +//! Uuid::parse_str("936DA01F9ABD4d9d80C702AF85C822A8")?; +//! println!("{}", my_uuid.to_urn()); +//! Ok(()) +//! } +//! ``` +//! +//! To create a new random (V4) UUID and print it out in hexadecimal form: +//! +//! ```ignore,rust +//! // Note that this requires the `v4` feature enabled in the uuid crate. +//! +//! use uuid::Uuid; +//! +//! fn main() -> Result<(), Box> { +//! #[cfg(feature = "v4")] { +//! let my_uuid = Uuid::new_v4()?; +//! println!("{}", my_uuid); +//! } +//! Ok(()) +//! } +//! ``` +//! +//! # Strings +//! +//! Examples of string representations: +//! +//! * simple: `936DA01F9ABD4d9d80C702AF85C822A8` +//! * hyphenated: `550e8400-e29b-41d4-a716-446655440000` +//! * urn: `urn:uuid:F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4` +//! +//! # References +//! +//! * [Wikipedia: Universally Unique Identifier](http://en.wikipedia.org/wiki/Universally_unique_identifier) +//! * [RFC4122: A Universally Unique IDentifier (UUID) URN Namespace](http://tools.ietf.org/html/rfc4122) +//! +//! [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen +//! [`cargo-web`]: https://crates.io/crates/cargo-web +//! [`stdweb`]: https://crates.io/crates/stdweb +//! [`Uuid`]: struct.Uuid.html +//! [`Uuid::new_v1`]: struct.Uuid.html#method.new_v1 +//! [`Uuid::new_v3`]: struct.Uuid.html#method.new_v3 +//! [`Uuid::new_v4`]: struct.Uuid.html#method.new_v4 +//! [`Uuid::new_v5`]: struct.Uuid.html#method.new_v5 +//! [`v1::ClockSequence`]: v1/trait.ClockSequence.html +//! [`v1::Context`]: v1/struct.Context.html + +#![no_std] +#![deny(missing_debug_implementations, missing_docs)] +#![doc( + html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", + html_favicon_url = "https://www.rust-lang.org/favicon.ico", + html_root_url = "https://docs.rs/uuid/0.8.2" +)] + +#[cfg(any(feature = "std", test))] +#[macro_use] +extern crate std; + +#[cfg(all(not(feature = "std"), not(test)))] +#[macro_use] +extern crate core as std; + +mod builder; +mod error; +mod parser; +mod prelude; + +pub mod adapter; +#[cfg(feature = "v1")] +pub mod v1; + +#[cfg(feature = "serde")] +mod serde_support; +#[cfg(feature = "slog")] +mod slog_support; +#[cfg(test)] +mod test_util; +#[cfg(all( + feature = "v3", + any( + not(target_arch = "wasm32"), + target_os = "wasi", + all( + target_arch = "wasm32", + any(feature = "stdweb", feature = "wasm-bindgen") + ) + ) +))] +mod v3; +#[cfg(all( + feature = "v4", + any( + not(target_arch = "wasm32"), + target_os = "wasi", + all( + target_arch = "wasm32", + any(feature = "stdweb", feature = "wasm-bindgen") + ) + ) +))] +mod v4; +#[cfg(all( + feature = "v5", + any( + not(target_arch = "wasm32"), + target_os = "wasi", + all( + target_arch = "wasm32", + any(feature = "stdweb", feature = "wasm-bindgen") + ) + ) +))] +mod v5; +#[cfg(all(windows, feature = "winapi"))] +mod winapi_support; + +use crate::std::{fmt, str}; + +pub use crate::error::Error; + +/// A builder struct for creating a UUID. +/// +/// # Examples +/// +/// Creating a v4 UUID from externally generated bytes: +/// +/// ``` +/// use uuid::{Builder, Variant, Version}; +/// +/// # let rng = || [ +/// # 70, 235, 208, 238, 14, 109, 67, 201, 185, 13, 204, 195, 90, +/// # 145, 63, 62, +/// # ]; +/// let random_bytes = rng(); +/// let uuid = Builder::from_bytes(random_bytes) +/// .set_variant(Variant::RFC4122) +/// .set_version(Version::Random) +/// .build(); +/// ``` +#[allow(missing_copy_implementations)] +#[derive(Debug)] +pub struct Builder(Bytes); + +/// A 128-bit (16 byte) buffer containing the ID. +pub type Bytes = [u8; 16]; + +/// The version of the UUID, denoting the generating algorithm. +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum Version { + /// Special case for `nil` UUID. + Nil = 0, + /// Version 1: MAC address. + Mac, + /// Version 2: DCE Security. + Dce, + /// Version 3: MD5 hash. + Md5, + /// Version 4: Random. + Random, + /// Version 5: SHA-1 hash. + Sha1, +} + +/// The reserved variants of UUIDs. +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum Variant { + /// Reserved by the NCS for backward compatibility. + NCS = 0, + /// As described in the RFC4122 Specification (default). + RFC4122, + /// Reserved by Microsoft for backward compatibility. + Microsoft, + /// Reserved for future expansion. + Future, +} + +/// A Universally Unique Identifier (UUID). +#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)] +#[repr(transparent)] +pub struct Uuid(Bytes); + +impl Uuid { + /// UUID namespace for Domain Name System (DNS). + pub const NAMESPACE_DNS: Self = Uuid([ + 0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, + 0x4f, 0xd4, 0x30, 0xc8, + ]); + + /// UUID namespace for ISO Object Identifiers (OIDs). + pub const NAMESPACE_OID: Self = Uuid([ + 0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, + 0x4f, 0xd4, 0x30, 0xc8, + ]); + + /// UUID namespace for Uniform Resource Locators (URLs). + pub const NAMESPACE_URL: Self = Uuid([ + 0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, + 0x4f, 0xd4, 0x30, 0xc8, + ]); + + /// UUID namespace for X.500 Distinguished Names (DNs). + pub const NAMESPACE_X500: Self = Uuid([ + 0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, + 0x4f, 0xd4, 0x30, 0xc8, + ]); + + /// Returns the variant of the UUID structure. + /// + /// This determines the interpretation of the structure of the UUID. + /// Currently only the RFC4122 variant is generated by this module. + /// + /// * [Variant Reference](http://tools.ietf.org/html/rfc4122#section-4.1.1) + pub fn get_variant(&self) -> Option { + match self.as_bytes()[8] { + x if x & 0x80 == 0x00 => Some(Variant::NCS), + x if x & 0xc0 == 0x80 => Some(Variant::RFC4122), + x if x & 0xe0 == 0xc0 => Some(Variant::Microsoft), + x if x & 0xe0 == 0xe0 => Some(Variant::Future), + _ => None, + } + } + + /// Returns the version number of the UUID. + /// + /// This represents the algorithm used to generate the contents. + /// + /// Currently only the Random (V4) algorithm is supported by this + /// module. There are security and privacy implications for using + /// older versions - see [Wikipedia: Universally Unique Identifier]( + /// http://en.wikipedia.org/wiki/Universally_unique_identifier) for + /// details. + /// + /// * [Version Reference](http://tools.ietf.org/html/rfc4122#section-4.1.3) + pub const fn get_version_num(&self) -> usize { + (self.as_bytes()[6] >> 4) as usize + } + + /// Returns the version of the UUID. + /// + /// This represents the algorithm used to generate the contents + pub fn get_version(&self) -> Option { + let v = self.as_bytes()[6] >> 4; + match v { + 0 if self.is_nil() => Some(Version::Nil), + 1 => Some(Version::Mac), + 2 => Some(Version::Dce), + 3 => Some(Version::Md5), + 4 => Some(Version::Random), + 5 => Some(Version::Sha1), + _ => None, + } + } + + /// Returns the four field values of the UUID in big-endian order. + /// + /// These values can be passed to the `from_fields()` method to get the + /// original `Uuid` back. + /// + /// * The first field value represents the first group of (eight) hex + /// digits, taken as a big-endian `u32` value. For V1 UUIDs, this field + /// represents the low 32 bits of the timestamp. + /// * The second field value represents the second group of (four) hex + /// digits, taken as a big-endian `u16` value. For V1 UUIDs, this field + /// represents the middle 16 bits of the timestamp. + /// * The third field value represents the third group of (four) hex digits, + /// taken as a big-endian `u16` value. The 4 most significant bits give + /// the UUID version, and for V1 UUIDs, the last 12 bits represent the + /// high 12 bits of the timestamp. + /// * The last field value represents the last two groups of four and twelve + /// hex digits, taken in order. The first 1-3 bits of this indicate the + /// UUID variant, and for V1 UUIDs, the next 13-15 bits indicate the clock + /// sequence and the last 48 bits indicate the node ID. + /// + /// # Examples + /// + /// ``` + /// use uuid::Uuid; + /// + /// fn main() -> Result<(), uuid::Error> { + /// let uuid = Uuid::nil(); + /// assert_eq!(uuid.as_fields(), (0, 0, 0, &[0u8; 8])); + /// + /// let uuid = Uuid::parse_str("936DA01F-9ABD-4D9D-80C7-02AF85C822A8")?; + /// assert_eq!( + /// uuid.as_fields(), + /// ( + /// 0x936DA01F, + /// 0x9ABD, + /// 0x4D9D, + /// b"\x80\xC7\x02\xAF\x85\xC8\x22\xA8" + /// ) + /// ); + /// + /// Ok(()) + /// } + /// ``` + pub fn as_fields(&self) -> (u32, u16, u16, &[u8; 8]) { + let d1 = u32::from(self.as_bytes()[0]) << 24 + | u32::from(self.as_bytes()[1]) << 16 + | u32::from(self.as_bytes()[2]) << 8 + | u32::from(self.as_bytes()[3]); + + let d2 = + u16::from(self.as_bytes()[4]) << 8 | u16::from(self.as_bytes()[5]); + + let d3 = + u16::from(self.as_bytes()[6]) << 8 | u16::from(self.as_bytes()[7]); + + let d4: &[u8; 8] = + unsafe { &*(self.as_bytes()[8..16].as_ptr() as *const [u8; 8]) }; + (d1, d2, d3, d4) + } + + /// Returns the four field values of the UUID in little-endian order. + /// + /// The bytes in the returned integer fields will + /// be converted from big-endian order. + /// + /// # Examples + /// + /// ``` + /// use uuid::Uuid; + /// + /// fn main() -> Result<(), uuid::Error> { + /// let uuid = Uuid::parse_str("936DA01F-9ABD-4D9D-80C7-02AF85C822A8")?; + /// assert_eq!( + /// uuid.to_fields_le(), + /// ( + /// 0x1FA06D93, + /// 0xBD9A, + /// 0x9D4D, + /// b"\x80\xC7\x02\xAF\x85\xC8\x22\xA8" + /// ) + /// ); + /// Ok(()) + /// } + /// ``` + pub fn to_fields_le(&self) -> (u32, u16, u16, &[u8; 8]) { + let d1 = u32::from(self.as_bytes()[0]) + | u32::from(self.as_bytes()[1]) << 8 + | u32::from(self.as_bytes()[2]) << 16 + | u32::from(self.as_bytes()[3]) << 24; + + let d2 = + u16::from(self.as_bytes()[4]) | u16::from(self.as_bytes()[5]) << 8; + + let d3 = + u16::from(self.as_bytes()[6]) | u16::from(self.as_bytes()[7]) << 8; + + let d4: &[u8; 8] = + unsafe { &*(self.as_bytes()[8..16].as_ptr() as *const [u8; 8]) }; + (d1, d2, d3, d4) + } + + /// Returns a 128bit value containing the UUID data. + /// + /// The bytes in the UUID will be packed into a `u128`, like the + /// [`Uuid::as_bytes`] method. + /// + /// # Examples + /// + /// ``` + /// use uuid::Uuid; + /// + /// fn main() -> Result<(), uuid::Error> { + /// let uuid = Uuid::parse_str("936DA01F-9ABD-4D9D-80C7-02AF85C822A8")?; + /// assert_eq!( + /// uuid.as_u128(), + /// 0x936DA01F9ABD4D9D80C702AF85C822A8, + /// ); + /// Ok(()) + /// } + /// ``` + pub fn as_u128(&self) -> u128 { + u128::from(self.as_bytes()[0]) << 120 + | u128::from(self.as_bytes()[1]) << 112 + | u128::from(self.as_bytes()[2]) << 104 + | u128::from(self.as_bytes()[3]) << 96 + | u128::from(self.as_bytes()[4]) << 88 + | u128::from(self.as_bytes()[5]) << 80 + | u128::from(self.as_bytes()[6]) << 72 + | u128::from(self.as_bytes()[7]) << 64 + | u128::from(self.as_bytes()[8]) << 56 + | u128::from(self.as_bytes()[9]) << 48 + | u128::from(self.as_bytes()[10]) << 40 + | u128::from(self.as_bytes()[11]) << 32 + | u128::from(self.as_bytes()[12]) << 24 + | u128::from(self.as_bytes()[13]) << 16 + | u128::from(self.as_bytes()[14]) << 8 + | u128::from(self.as_bytes()[15]) + } + + /// Returns a 128bit little-endian value containing the UUID data. + /// + /// The bytes in the UUID will be reversed and packed into a `u128`. + /// Note that this will produce a different result than + /// [`Uuid::to_fields_le`], because the entire UUID is reversed, rather + /// than reversing the individual fields in-place. + /// + /// # Examples + /// + /// ``` + /// use uuid::Uuid; + /// + /// fn main() -> Result<(), uuid::Error> { + /// let uuid = Uuid::parse_str("936DA01F-9ABD-4D9D-80C7-02AF85C822A8")?; + /// + /// assert_eq!( + /// uuid.to_u128_le(), + /// 0xA822C885AF02C7809D4DBD9A1FA06D93, + /// ); + /// Ok(()) + /// } + /// ``` + pub fn to_u128_le(&self) -> u128 { + u128::from(self.as_bytes()[0]) + | u128::from(self.as_bytes()[1]) << 8 + | u128::from(self.as_bytes()[2]) << 16 + | u128::from(self.as_bytes()[3]) << 24 + | u128::from(self.as_bytes()[4]) << 32 + | u128::from(self.as_bytes()[5]) << 40 + | u128::from(self.as_bytes()[6]) << 48 + | u128::from(self.as_bytes()[7]) << 56 + | u128::from(self.as_bytes()[8]) << 64 + | u128::from(self.as_bytes()[9]) << 72 + | u128::from(self.as_bytes()[10]) << 80 + | u128::from(self.as_bytes()[11]) << 88 + | u128::from(self.as_bytes()[12]) << 96 + | u128::from(self.as_bytes()[13]) << 104 + | u128::from(self.as_bytes()[14]) << 112 + | u128::from(self.as_bytes()[15]) << 120 + } + + /// Returns an array of 16 octets containing the UUID data. + pub const fn as_bytes(&self) -> &Bytes { + &self.0 + } + + /// Tests if the UUID is nil. + pub fn is_nil(&self) -> bool { + self.as_bytes().iter().all(|&b| b == 0) + } + + /// A buffer that can be used for `encode_...` calls, that is + /// guaranteed to be long enough for any of the adapters. + /// + /// # Examples + /// + /// ```rust + /// use uuid::Uuid; + /// + /// let uuid = Uuid::nil(); + /// + /// assert_eq!( + /// uuid.to_simple().encode_lower(&mut Uuid::encode_buffer()), + /// "00000000000000000000000000000000" + /// ); + /// + /// assert_eq!( + /// uuid.to_hyphenated() + /// .encode_lower(&mut Uuid::encode_buffer()), + /// "00000000-0000-0000-0000-000000000000" + /// ); + /// + /// assert_eq!( + /// uuid.to_urn().encode_lower(&mut Uuid::encode_buffer()), + /// "urn:uuid:00000000-0000-0000-0000-000000000000" + /// ); + /// ``` + pub const fn encode_buffer() -> [u8; adapter::Urn::LENGTH] { + [0; adapter::Urn::LENGTH] + } +} + +impl fmt::Debug for Uuid { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::LowerHex::fmt(self, f) + } +} + +impl fmt::Display for Uuid { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::LowerHex::fmt(self, f) + } +} + +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::Future => write!(f, "Future"), + } + } +} + +impl fmt::LowerHex for Uuid { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::LowerHex::fmt(&self.to_hyphenated_ref(), f) + } +} + +impl fmt::UpperHex for Uuid { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::UpperHex::fmt(&self.to_hyphenated_ref(), f) + } +} + +impl str::FromStr for Uuid { + type Err = Error; + + fn from_str(uuid_str: &str) -> Result { + Uuid::parse_str(uuid_str) + } +} + +impl Default for Uuid { + #[inline] + fn default() -> Self { + Uuid::nil() + } +} + +#[cfg(test)] +mod tests { + use crate::{ + prelude::*, + std::string::{String, ToString}, + test_util, + }; + + macro_rules! check { + ($buf:ident, $format:expr, $target:expr, $len:expr, $cond:expr) => { + $buf.clear(); + write!($buf, $format, $target).unwrap(); + assert!($buf.len() == $len); + assert!($buf.chars().all($cond), "{}", $buf); + }; + } + + #[test] + fn test_uuid_compare() { + let uuid1 = test_util::new(); + let uuid2 = test_util::new2(); + + assert_eq!(uuid1, uuid1); + assert_eq!(uuid2, uuid2); + + assert_ne!(uuid1, uuid2); + assert_ne!(uuid2, uuid1); + } + + #[test] + fn test_uuid_default() { + let default_uuid = Uuid::default(); + let nil_uuid = Uuid::nil(); + + assert_eq!(default_uuid, nil_uuid); + } + + #[test] + fn test_uuid_display() { + use super::fmt::Write; + + let uuid = test_util::new(); + let s = uuid.to_string(); + let mut buffer = String::new(); + + assert_eq!(s, uuid.to_hyphenated().to_string()); + + check!(buffer, "{}", uuid, 36, |c| c.is_lowercase() + || c.is_digit(10) + || c == '-'); + } + + #[test] + fn test_uuid_lowerhex() { + use super::fmt::Write; + + let mut buffer = String::new(); + let uuid = test_util::new(); + + check!(buffer, "{:x}", uuid, 36, |c| c.is_lowercase() + || c.is_digit(10) + || c == '-'); + } + + // noinspection RsAssertEqual + #[test] + fn test_uuid_operator_eq() { + let uuid1 = test_util::new(); + let uuid1_dup = uuid1.clone(); + let uuid2 = test_util::new2(); + + assert!(uuid1 == uuid1); + assert!(uuid1 == uuid1_dup); + assert!(uuid1_dup == uuid1); + + assert!(uuid1 != uuid2); + assert!(uuid2 != uuid1); + assert!(uuid1_dup != uuid2); + assert!(uuid2 != uuid1_dup); + } + + #[test] + fn test_uuid_to_string() { + use super::fmt::Write; + + let uuid = test_util::new(); + let s = uuid.to_string(); + let mut buffer = String::new(); + + assert_eq!(s.len(), 36); + + check!(buffer, "{}", s, 36, |c| c.is_lowercase() + || c.is_digit(10) + || c == '-'); + } + + #[test] + fn test_uuid_upperhex() { + use super::fmt::Write; + + let mut buffer = String::new(); + let uuid = test_util::new(); + + check!(buffer, "{:X}", uuid, 36, |c| c.is_uppercase() + || c.is_digit(10) + || c == '-'); + } + + #[test] + fn test_nil() { + let nil = Uuid::nil(); + let not_nil = test_util::new(); + let from_bytes = Uuid::from_bytes([ + 4, 54, 67, 12, 43, 2, 2, 76, 32, 50, 87, 5, 1, 33, 43, 87, + ]); + + assert_eq!(from_bytes.get_version(), None); + + assert!(nil.is_nil()); + assert!(!not_nil.is_nil()); + + assert_eq!(nil.get_version(), Some(Version::Nil)); + assert_eq!(not_nil.get_version(), Some(Version::Random)) + } + + #[test] + fn test_predefined_namespaces() { + assert_eq!( + Uuid::NAMESPACE_DNS.to_hyphenated().to_string(), + "6ba7b810-9dad-11d1-80b4-00c04fd430c8" + ); + assert_eq!( + Uuid::NAMESPACE_URL.to_hyphenated().to_string(), + "6ba7b811-9dad-11d1-80b4-00c04fd430c8" + ); + assert_eq!( + Uuid::NAMESPACE_OID.to_hyphenated().to_string(), + "6ba7b812-9dad-11d1-80b4-00c04fd430c8" + ); + assert_eq!( + Uuid::NAMESPACE_X500.to_hyphenated().to_string(), + "6ba7b814-9dad-11d1-80b4-00c04fd430c8" + ); + } + + #[cfg(feature = "v3")] + #[test] + fn test_get_version_v3() { + let uuid = + Uuid::new_v3(&Uuid::NAMESPACE_DNS, "rust-lang.org".as_bytes()); + + assert_eq!(uuid.get_version().unwrap(), Version::Md5); + assert_eq!(uuid.get_version_num(), 3); + } + + #[test] + fn test_get_variant() { + let uuid1 = test_util::new(); + let uuid2 = + Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap(); + let uuid3 = + Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8").unwrap(); + let uuid4 = + Uuid::parse_str("936DA01F9ABD4d9dC0C702AF85C822A8").unwrap(); + let uuid5 = + Uuid::parse_str("F9168C5E-CEB2-4faa-D6BF-329BF39FA1E4").unwrap(); + let uuid6 = + Uuid::parse_str("f81d4fae-7dec-11d0-7765-00a0c91e6bf6").unwrap(); + + assert_eq!(uuid1.get_variant().unwrap(), Variant::RFC4122); + assert_eq!(uuid2.get_variant().unwrap(), Variant::RFC4122); + assert_eq!(uuid3.get_variant().unwrap(), Variant::RFC4122); + assert_eq!(uuid4.get_variant().unwrap(), Variant::Microsoft); + assert_eq!(uuid5.get_variant().unwrap(), Variant::Microsoft); + assert_eq!(uuid6.get_variant().unwrap(), Variant::NCS); + } + + #[test] + fn test_to_simple_string() { + let uuid1 = test_util::new(); + let s = uuid1.to_simple().to_string(); + + assert_eq!(s.len(), 32); + assert!(s.chars().all(|c| c.is_digit(16))); + } + + #[test] + fn test_to_hyphenated_string() { + let uuid1 = test_util::new(); + let s = uuid1.to_hyphenated().to_string(); + + assert!(s.len() == 36); + assert!(s.chars().all(|c| c.is_digit(16) || c == '-')); + } + + #[test] + fn test_upper_lower_hex() { + use std::fmt::Write; + + let mut buf = String::new(); + let u = test_util::new(); + + macro_rules! check { + ($buf:ident, $format:expr, $target:expr, $len:expr, $cond:expr) => { + $buf.clear(); + write!($buf, $format, $target).unwrap(); + assert!(buf.len() == $len); + assert!($buf.chars().all($cond), "{}", $buf); + }; + } + + check!(buf, "{:X}", u, 36, |c| c.is_uppercase() + || c.is_digit(10) + || c == '-'); + check!(buf, "{:X}", u.to_hyphenated(), 36, |c| c.is_uppercase() + || c.is_digit(10) + || c == '-'); + check!(buf, "{:X}", u.to_simple(), 32, |c| c.is_uppercase() + || c.is_digit(10)); + + check!(buf, "{:x}", u.to_hyphenated(), 36, |c| c.is_lowercase() + || c.is_digit(10) + || c == '-'); + check!(buf, "{:x}", u.to_simple(), 32, |c| c.is_lowercase() + || c.is_digit(10)); + } + + #[test] + fn test_to_urn_string() { + let uuid1 = test_util::new(); + let ss = uuid1.to_urn().to_string(); + let s = &ss[9..]; + + assert!(ss.starts_with("urn:uuid:")); + assert_eq!(s.len(), 36); + assert!(s.chars().all(|c| c.is_digit(16) || c == '-')); + } + + #[test] + fn test_to_simple_string_matching() { + let uuid1 = test_util::new(); + + let hs = uuid1.to_hyphenated().to_string(); + let ss = uuid1.to_simple().to_string(); + + let hsn = hs.chars().filter(|&c| c != '-').collect::(); + + assert_eq!(hsn, ss); + } + + #[test] + fn test_string_roundtrip() { + let uuid = test_util::new(); + + let hs = uuid.to_hyphenated().to_string(); + let uuid_hs = Uuid::parse_str(&hs).unwrap(); + assert_eq!(uuid_hs, uuid); + + let ss = uuid.to_string(); + let uuid_ss = Uuid::parse_str(&ss).unwrap(); + assert_eq!(uuid_ss, uuid); + } + + #[test] + fn test_from_fields() { + let d1: u32 = 0xa1a2a3a4; + let d2: u16 = 0xb1b2; + let d3: u16 = 0xc1c2; + let d4 = [0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8]; + + let u = Uuid::from_fields(d1, d2, d3, &d4).unwrap(); + + let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8"; + let result = u.to_simple().to_string(); + assert_eq!(result, expected); + } + + #[test] + fn test_from_fields_le() { + let d1: u32 = 0xa4a3a2a1; + let d2: u16 = 0xb2b1; + let d3: u16 = 0xc2c1; + let d4 = [0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8]; + + let u = Uuid::from_fields_le(d1, d2, d3, &d4).unwrap(); + + let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8"; + let result = u.to_simple().to_string(); + assert_eq!(result, expected); + } + + #[test] + fn test_as_fields() { + let u = test_util::new(); + let (d1, d2, d3, d4) = u.as_fields(); + + assert_ne!(d1, 0); + assert_ne!(d2, 0); + assert_ne!(d3, 0); + assert_eq!(d4.len(), 8); + assert!(!d4.iter().all(|&b| b == 0)); + } + + #[test] + fn test_fields_roundtrip() { + let d1_in: u32 = 0xa1a2a3a4; + let d2_in: u16 = 0xb1b2; + let d3_in: u16 = 0xc1c2; + let d4_in = &[0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8]; + + let u = Uuid::from_fields(d1_in, d2_in, d3_in, d4_in).unwrap(); + let (d1_out, d2_out, d3_out, d4_out) = u.as_fields(); + + assert_eq!(d1_in, d1_out); + assert_eq!(d2_in, d2_out); + assert_eq!(d3_in, d3_out); + assert_eq!(d4_in, d4_out); + } + + #[test] + fn test_fields_le_roundtrip() { + let d1_in: u32 = 0xa4a3a2a1; + let d2_in: u16 = 0xb2b1; + let d3_in: u16 = 0xc2c1; + let d4_in = &[0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8]; + + let u = Uuid::from_fields_le(d1_in, d2_in, d3_in, d4_in).unwrap(); + let (d1_out, d2_out, d3_out, d4_out) = u.to_fields_le(); + + assert_eq!(d1_in, d1_out); + assert_eq!(d2_in, d2_out); + assert_eq!(d3_in, d3_out); + assert_eq!(d4_in, d4_out); + } + + #[test] + fn test_fields_le_are_actually_le() { + let d1_in: u32 = 0xa1a2a3a4; + let d2_in: u16 = 0xb1b2; + let d3_in: u16 = 0xc1c2; + let d4_in = &[0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8]; + + let u = Uuid::from_fields(d1_in, d2_in, d3_in, d4_in).unwrap(); + let (d1_out, d2_out, d3_out, d4_out) = u.to_fields_le(); + + assert_eq!(d1_in, d1_out.swap_bytes()); + assert_eq!(d2_in, d2_out.swap_bytes()); + assert_eq!(d3_in, d3_out.swap_bytes()); + assert_eq!(d4_in, d4_out); + } + + #[test] + fn test_from_u128() { + let v_in: u128 = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8; + + let u = Uuid::from_u128(v_in); + + let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8"; + let result = u.to_simple().to_string(); + assert_eq!(result, expected); + } + + #[test] + fn test_from_u128_le() { + let v_in: u128 = 0xd8d7d6d5d4d3d2d1c2c1b2b1a4a3a2a1; + + let u = Uuid::from_u128_le(v_in); + + let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8"; + let result = u.to_simple().to_string(); + assert_eq!(result, expected); + } + + #[test] + fn test_u128_roundtrip() { + let v_in: u128 = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8; + + let u = Uuid::from_u128(v_in); + let v_out = u.as_u128(); + + assert_eq!(v_in, v_out); + } + + #[test] + fn test_u128_le_roundtrip() { + let v_in: u128 = 0xd8d7d6d5d4d3d2d1c2c1b2b1a4a3a2a1; + + let u = Uuid::from_u128_le(v_in); + let v_out = u.to_u128_le(); + + assert_eq!(v_in, v_out); + } + + #[test] + fn test_u128_le_is_actually_le() { + let v_in: u128 = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8; + + let u = Uuid::from_u128(v_in); + let v_out = u.to_u128_le(); + + assert_eq!(v_in, v_out.swap_bytes()); + } + + #[test] + fn test_from_slice() { + let b = [ + 0xa1, 0xa2, 0xa3, 0xa4, 0xb1, 0xb2, 0xc1, 0xc2, 0xd1, 0xd2, 0xd3, + 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, + ]; + + let u = Uuid::from_slice(&b).unwrap(); + let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8"; + + assert_eq!(u.to_simple().to_string(), expected); + } + + #[test] + fn test_from_bytes() { + let b = [ + 0xa1, 0xa2, 0xa3, 0xa4, 0xb1, 0xb2, 0xc1, 0xc2, 0xd1, 0xd2, 0xd3, + 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, + ]; + + let u = Uuid::from_bytes(b); + let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8"; + + assert_eq!(u.to_simple().to_string(), expected); + } + + #[test] + fn test_as_bytes() { + let u = test_util::new(); + let ub = u.as_bytes(); + + assert_eq!(ub.len(), 16); + assert!(!ub.iter().all(|&b| b == 0)); + } + + #[test] + fn test_bytes_roundtrip() { + let b_in: crate::Bytes = [ + 0xa1, 0xa2, 0xa3, 0xa4, 0xb1, 0xb2, 0xc1, 0xc2, 0xd1, 0xd2, 0xd3, + 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, + ]; + + let u = Uuid::from_slice(&b_in).unwrap(); + + let b_out = u.as_bytes(); + + assert_eq!(&b_in, b_out); + } + + #[test] + fn test_iterbytes_impl_for_uuid() { + let mut set = std::collections::HashSet::new(); + let id1 = test_util::new(); + let id2 = test_util::new2(); + set.insert(id1.clone()); + + assert!(set.contains(&id1)); + assert!(!set.contains(&id2)); + } +} -- cgit v1.2.3