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/adapter/compact.rs | 81 +++ vendor/uuid/src/adapter/mod.rs | 1027 ++++++++++++++++++++++++++++++++++ vendor/uuid/src/builder/error.rs | 52 ++ vendor/uuid/src/builder/mod.rs | 473 ++++++++++++++++ vendor/uuid/src/error.rs | 79 +++ vendor/uuid/src/lib.rs | 1070 ++++++++++++++++++++++++++++++++++++ vendor/uuid/src/parser/error.rs | 149 +++++ vendor/uuid/src/parser/mod.rs | 447 +++++++++++++++ vendor/uuid/src/prelude.rs | 47 ++ vendor/uuid/src/serde_support.rs | 125 +++++ vendor/uuid/src/slog_support.rs | 39 ++ vendor/uuid/src/test_util.rs | 26 + vendor/uuid/src/v1.rs | 326 +++++++++++ vendor/uuid/src/v3.rs | 146 +++++ vendor/uuid/src/v4.rs | 60 ++ vendor/uuid/src/v5.rs | 158 ++++++ vendor/uuid/src/winapi_support.rs | 79 +++ 17 files changed, 4384 insertions(+) create mode 100644 vendor/uuid/src/adapter/compact.rs create mode 100644 vendor/uuid/src/adapter/mod.rs create mode 100644 vendor/uuid/src/builder/error.rs create mode 100644 vendor/uuid/src/builder/mod.rs create mode 100644 vendor/uuid/src/error.rs create mode 100644 vendor/uuid/src/lib.rs create mode 100644 vendor/uuid/src/parser/error.rs create mode 100644 vendor/uuid/src/parser/mod.rs create mode 100644 vendor/uuid/src/prelude.rs create mode 100644 vendor/uuid/src/serde_support.rs create mode 100644 vendor/uuid/src/slog_support.rs create mode 100644 vendor/uuid/src/test_util.rs create mode 100644 vendor/uuid/src/v1.rs create mode 100644 vendor/uuid/src/v3.rs create mode 100644 vendor/uuid/src/v4.rs create mode 100644 vendor/uuid/src/v5.rs create mode 100644 vendor/uuid/src/winapi_support.rs (limited to 'vendor/uuid/src') diff --git a/vendor/uuid/src/adapter/compact.rs b/vendor/uuid/src/adapter/compact.rs new file mode 100644 index 000000000..1b53682e3 --- /dev/null +++ b/vendor/uuid/src/adapter/compact.rs @@ -0,0 +1,81 @@ +//! Module for use with `#[serde(with = "...")]` to serialize a [`Uuid`] +//! as a `[u8; 16]`. +//! +//! [`Uuid`]: ../../struct.Uuid.html + +/// Serializer for a [`Uuid`] into a `[u8; 16]` +/// +/// [`Uuid`]: ../../struct.Uuid.html +pub fn serialize(u: &crate::Uuid, serializer: S) -> Result +where + S: serde::Serializer, +{ + serde::Serialize::serialize(u.as_bytes(), serializer) +} + +/// Deserializer from a `[u8; 16]` into a [`Uuid`] +/// +/// [`Uuid`]: ../../struct.Uuid.html +pub fn deserialize<'de, D>(deserializer: D) -> Result +where + D: serde::Deserializer<'de>, +{ + let bytes: [u8; 16] = serde::Deserialize::deserialize(deserializer)?; + + Ok(crate::Uuid::from_bytes(bytes)) +} + +#[cfg(test)] +mod tests { + + use serde_test; + + #[test] + fn test_serialize_compact() { + #[derive( + serde_derive::Serialize, Debug, serde_derive::Deserialize, PartialEq, + )] + struct UuidContainer { + #[serde(with = "super")] + u: crate::Uuid, + } + use serde_test::Configure; + + let uuid_bytes = b"F9168C5E-CEB2-4F"; + let container = UuidContainer { + u: crate::Uuid::from_slice(uuid_bytes).unwrap(), + }; + + // more complex because of the struct wrapping the actual UUID + // serialization + serde_test::assert_tokens( + &container.compact(), + &[ + serde_test::Token::Struct { + name: "UuidContainer", + len: 1, + }, + serde_test::Token::Str("u"), + serde_test::Token::Tuple { len: 16 }, + serde_test::Token::U8(uuid_bytes[0]), + serde_test::Token::U8(uuid_bytes[1]), + serde_test::Token::U8(uuid_bytes[2]), + serde_test::Token::U8(uuid_bytes[3]), + serde_test::Token::U8(uuid_bytes[4]), + serde_test::Token::U8(uuid_bytes[5]), + serde_test::Token::U8(uuid_bytes[6]), + serde_test::Token::U8(uuid_bytes[7]), + serde_test::Token::U8(uuid_bytes[8]), + serde_test::Token::U8(uuid_bytes[9]), + serde_test::Token::U8(uuid_bytes[10]), + serde_test::Token::U8(uuid_bytes[11]), + serde_test::Token::U8(uuid_bytes[12]), + serde_test::Token::U8(uuid_bytes[13]), + serde_test::Token::U8(uuid_bytes[14]), + serde_test::Token::U8(uuid_bytes[15]), + serde_test::Token::TupleEnd, + serde_test::Token::StructEnd, + ], + ) + } +} diff --git a/vendor/uuid/src/adapter/mod.rs b/vendor/uuid/src/adapter/mod.rs new file mode 100644 index 000000000..412920e6b --- /dev/null +++ b/vendor/uuid/src/adapter/mod.rs @@ -0,0 +1,1027 @@ +// 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. + +//! Adapters for various formats for UUIDs + +use crate::prelude::*; +use crate::std::{fmt, str}; + +#[cfg(feature = "serde")] +pub mod compact; + +/// An adaptor for formatting an [`Uuid`] as a hyphenated string. +/// +/// Takes an owned instance of the [`Uuid`]. +/// +/// [`Uuid`]: ../struct.Uuid.html +#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct Hyphenated(Uuid); + +/// An adaptor for formatting an [`Uuid`] as a hyphenated string. +/// +/// Takes a reference of the [`Uuid`]. +/// +/// [`Uuid`]: ../struct.Uuid.html +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct HyphenatedRef<'a>(&'a Uuid); + +/// An adaptor for formatting an [`Uuid`] as a simple string. +/// +/// Takes an owned instance of the [`Uuid`]. +/// +/// [`Uuid`]: ../struct.Uuid.html +#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct Simple(Uuid); + +/// An adaptor for formatting an [`Uuid`] as a simple string. +/// +/// Takes a reference of the [`Uuid`]. +/// +/// [`Uuid`]: ../struct.Uuid.html +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct SimpleRef<'a>(&'a Uuid); + +/// An adaptor for formatting an [`Uuid`] as a URN string. +/// +/// Takes an owned instance of the [`Uuid`]. +/// +/// [`Uuid`]: ../struct.Uuid.html +#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct Urn(Uuid); + +/// An adaptor for formatting an [`Uuid`] as a URN string. +/// +/// Takes a reference of the [`Uuid`]. +/// +/// [`Uuid`]: ../struct.Uuid.html +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct UrnRef<'a>(&'a Uuid); + +impl Uuid { + /// Get a [`Hyphenated`] formatter. + /// + /// [`Hyphenated`]: adapter/struct.Hyphenated.html + #[inline] + pub const fn to_hyphenated(self) -> Hyphenated { + Hyphenated::from_uuid(self) + } + + /// Get a borrowed [`HyphenatedRef`] formatter. + /// + /// [`HyphenatedRef`]: adapter/struct.HyphenatedRef.html + #[inline] + pub const fn to_hyphenated_ref(&self) -> HyphenatedRef<'_> { + HyphenatedRef::from_uuid_ref(self) + } + + /// Get a [`Simple`] formatter. + /// + /// [`Simple`]: adapter/struct.Simple.html + #[inline] + pub const fn to_simple(self) -> Simple { + Simple::from_uuid(self) + } + + /// Get a borrowed [`SimpleRef`] formatter. + /// + /// [`SimpleRef`]: adapter/struct.SimpleRef.html + #[inline] + pub const fn to_simple_ref(&self) -> SimpleRef<'_> { + SimpleRef::from_uuid_ref(self) + } + + /// Get a [`Urn`] formatter. + /// + /// [`Uuid`]: ../struct.Uuid.html + /// [`Urn`]: adapter/struct.Urn.html + #[inline] + pub const fn to_urn(self) -> Urn { + Urn::from_uuid(self) + } + + /// Get a borrowed [`UrnRef`] formatter. + /// + /// [`Uuid`]: ../struct.Uuid.html + /// [`UrnRef`]: adapter/struct.UrnRef.html + #[inline] + pub const fn to_urn_ref(&self) -> UrnRef<'_> { + UrnRef::from_uuid_ref(self) + } +} + +const UPPER: [u8; 16] = [ + b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'A', b'B', + b'C', b'D', b'E', b'F', +]; +const LOWER: [u8; 16] = [ + b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'a', b'b', + b'c', b'd', b'e', b'f', +]; +/// The segments of a UUID's [u8; 16] corresponding to each group. +const BYTE_POSITIONS: [usize; 6] = [0, 4, 6, 8, 10, 16]; +/// The locations that hyphens are written into the buffer, after each +/// group. +const HYPHEN_POSITIONS: [usize; 4] = [8, 13, 18, 23]; + +/// Encodes the `uuid` possibly with hyphens, and possibly in upper +/// case, to full_buffer[start..] and returns the str sliced from +/// full_buffer[..start + encoded_length]. +/// +/// The `start` parameter allows writing a prefix (such as +/// "urn:uuid:") to the buffer that's included in the final encoded +/// UUID. +#[allow(clippy::needless_range_loop)] +fn encode<'a>( + full_buffer: &'a mut [u8], + start: usize, + uuid: &Uuid, + hyphens: bool, + upper: bool, +) -> &'a mut str { + let len = if hyphens { 36 } else { 32 }; + + { + let buffer = &mut full_buffer[start..start + len]; + let bytes = uuid.as_bytes(); + + let hex = if upper { &UPPER } else { &LOWER }; + + for group in 0..5 { + // If we're writing hyphens, we need to shift the output + // location along by how many of them have been written + // before this point. That's exactly the (0-indexed) group + // number. + let hyphens_before = if hyphens { group } else { 0 }; + for idx in BYTE_POSITIONS[group]..BYTE_POSITIONS[group + 1] { + let b = bytes[idx]; + let out_idx = hyphens_before + 2 * idx; + + buffer[out_idx] = hex[(b >> 4) as usize]; + buffer[out_idx + 1] = hex[(b & 0b1111) as usize]; + } + + if group != 4 && hyphens { + buffer[HYPHEN_POSITIONS[group]] = b'-'; + } + } + } + + str::from_utf8_mut(&mut full_buffer[..start + len]) + .expect("found non-ASCII output characters while encoding a UUID") +} + +impl Hyphenated { + /// The length of a hyphenated [`Uuid`] string. + /// + /// [`Uuid`]: ../struct.Uuid.html + pub const LENGTH: usize = 36; + + /// Creates a [`Hyphenated`] from a [`Uuid`]. + /// + /// [`Uuid`]: ../struct.Uuid.html + /// [`Hyphenated`]: struct.Hyphenated.html + pub const fn from_uuid(uuid: Uuid) -> Self { + Hyphenated(uuid) + } + + /// Writes the [`Uuid`] as a lower-case hyphenated string to + /// `buffer`, and returns the subslice of the buffer that contains the + /// encoded UUID. + /// + /// This is slightly more efficient than using the formatting + /// infrastructure as it avoids virtual calls, and may avoid + /// double buffering. + /// + /// [`Uuid`]: ../struct.Uuid.html + /// + /// # Panics + /// + /// Panics if the buffer is not large enough: it must have length at least + /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a + /// sufficiently-large temporary buffer. + /// + /// [`LENGTH`]: #associatedconstant.LENGTH + /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer + /// + /// # Examples + /// + /// ```rust + /// use uuid::Uuid; + /// + /// fn main() -> Result<(), uuid::Error> { + /// let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8")?; + /// + /// // the encoded portion is returned + /// assert_eq!( + /// uuid.to_hyphenated() + /// .encode_lower(&mut Uuid::encode_buffer()), + /// "936da01f-9abd-4d9d-80c7-02af85c822a8" + /// ); + /// + /// // the buffer is mutated directly, and trailing contents remains + /// let mut buf = [b'!'; 40]; + /// uuid.to_hyphenated().encode_lower(&mut buf); + /// assert_eq!( + /// &buf as &[_], + /// b"936da01f-9abd-4d9d-80c7-02af85c822a8!!!!" as &[_] + /// ); + /// + /// Ok(()) + /// } + /// ``` + /// */ + pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { + encode(buffer, 0, &self.0, true, false) + } + + /// Writes the [`Uuid`] as an upper-case hyphenated string to + /// `buffer`, and returns the subslice of the buffer that contains the + /// encoded UUID. + /// + /// This is slightly more efficient than using the formatting + /// infrastructure as it avoids virtual calls, and may avoid + /// double buffering. + /// + /// [`Uuid`]: ../struct.Uuid.html + /// + /// # Panics + /// + /// Panics if the buffer is not large enough: it must have length at least + /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a + /// sufficiently-large temporary buffer. + /// + /// [`LENGTH`]: #associatedconstant.LENGTH + /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer + /// + /// # Examples + /// + /// ```rust + /// use uuid::Uuid; + /// + /// fn main() -> Result<(), uuid::Error> { + /// let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8")?; + /// + /// // the encoded portion is returned + /// assert_eq!( + /// uuid.to_hyphenated() + /// .encode_upper(&mut Uuid::encode_buffer()), + /// "936DA01F-9ABD-4D9D-80C7-02AF85C822A8" + /// ); + /// + /// // the buffer is mutated directly, and trailing contents remains + /// let mut buf = [b'!'; 40]; + /// uuid.to_hyphenated().encode_upper(&mut buf); + /// assert_eq!( + /// &buf as &[_], + /// b"936DA01F-9ABD-4D9D-80C7-02AF85C822A8!!!!" as &[_] + /// ); + /// + /// Ok(()) + /// } + /// ``` + /// */ + pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { + encode(buffer, 0, &self.0, true, true) + } +} + +impl<'a> HyphenatedRef<'a> { + /// The length of a hyphenated [`Uuid`] string. + /// + /// [`Uuid`]: ../struct.Uuid.html + pub const LENGTH: usize = 36; + + /// Creates a [`HyphenatedRef`] from a [`Uuid`] reference. + /// + /// [`Uuid`]: ../struct.Uuid.html + /// [`HyphenatedRef`]: struct.HyphenatedRef.html + pub const fn from_uuid_ref(uuid: &'a Uuid) -> Self { + HyphenatedRef(uuid) + } + + /// Writes the [`Uuid`] as a lower-case hyphenated string to + /// `buffer`, and returns the subslice of the buffer that contains the + /// encoded UUID. + /// + /// This is slightly more efficient than using the formatting + /// infrastructure as it avoids virtual calls, and may avoid + /// double buffering. + /// + /// [`Uuid`]: ../struct.Uuid.html + /// + /// # Panics + /// + /// Panics if the buffer is not large enough: it must have length at least + /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a + /// sufficiently-large temporary buffer. + /// + /// [`LENGTH`]: #associatedconstant.LENGTH + /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer + /// + /// # Examples + /// + /// ```rust + /// use uuid::Uuid; + /// + /// fn main() -> Result<(), uuid::Error> { + /// let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8")?; + /// + /// // the encoded portion is returned + /// assert_eq!( + /// uuid.to_hyphenated() + /// .encode_lower(&mut Uuid::encode_buffer()), + /// "936da01f-9abd-4d9d-80c7-02af85c822a8" + /// ); + /// + /// // the buffer is mutated directly, and trailing contents remains + /// let mut buf = [b'!'; 40]; + /// uuid.to_hyphenated().encode_lower(&mut buf); + /// assert_eq!( + /// uuid.to_hyphenated().encode_lower(&mut buf), + /// "936da01f-9abd-4d9d-80c7-02af85c822a8" + /// ); + /// assert_eq!( + /// &buf as &[_], + /// b"936da01f-9abd-4d9d-80c7-02af85c822a8!!!!" as &[_] + /// ); + /// + /// Ok(()) + /// } + /// ``` + /// */ + pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { + encode(buffer, 0, self.0, true, false) + } + + /// Writes the [`Uuid`] as an upper-case hyphenated string to + /// `buffer`, and returns the subslice of the buffer that contains the + /// encoded UUID. + /// + /// This is slightly more efficient than using the formatting + /// infrastructure as it avoids virtual calls, and may avoid + /// double buffering. + /// + /// [`Uuid`]: ../struct.Uuid.html + /// + /// # Panics + /// + /// Panics if the buffer is not large enough: it must have length at least + /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a + /// sufficiently-large temporary buffer. + /// + /// [`LENGTH`]: #associatedconstant.LENGTH + /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer + /// + /// # Examples + /// + /// ```rust + /// use uuid::Uuid; + /// + /// fn main() -> Result<(), uuid::Error> { + /// let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8")?; + /// + /// // the encoded portion is returned + /// assert_eq!( + /// uuid.to_hyphenated() + /// .encode_upper(&mut Uuid::encode_buffer()), + /// "936DA01F-9ABD-4D9D-80C7-02AF85C822A8" + /// ); + /// + /// // the buffer is mutated directly, and trailing contents remains + /// let mut buf = [b'!'; 40]; + /// assert_eq!( + /// uuid.to_hyphenated().encode_upper(&mut buf), + /// "936DA01F-9ABD-4D9D-80C7-02AF85C822A8" + /// ); + /// assert_eq!( + /// &buf as &[_], + /// b"936DA01F-9ABD-4D9D-80C7-02AF85C822A8!!!!" as &[_] + /// ); + /// + /// Ok(()) + /// } + /// ``` + /// */ + pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { + encode(buffer, 0, self.0, true, true) + } +} + +impl Simple { + /// The length of a simple [`Uuid`] string. + /// + /// [`Uuid`]: ../struct.Uuid.html + pub const LENGTH: usize = 32; + + /// Creates a [`Simple`] from a [`Uuid`]. + /// + /// [`Uuid`]: ../struct.Uuid.html + /// [`Simple`]: struct.Simple.html + pub const fn from_uuid(uuid: Uuid) -> Self { + Simple(uuid) + } + + /// Writes the [`Uuid`] as a lower-case simple string to `buffer`, + /// and returns the subslice of the buffer that contains the encoded UUID. + /// + /// This is slightly more efficient than using the formatting + /// infrastructure as it avoids virtual calls, and may avoid + /// double buffering. + /// + /// [`Uuid`]: ../struct.Uuid.html + /// + /// # Panics + /// + /// Panics if the buffer is not large enough: it must have length at least + /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a + /// sufficiently-large temporary buffer. + /// + /// [`LENGTH`]: #associatedconstant.LENGTH + /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer + /// + /// # Examples + /// + /// ```rust + /// use uuid::Uuid; + /// + /// fn main() -> Result<(), uuid::Error> { + /// let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8")?; + /// + /// // the encoded portion is returned + /// assert_eq!( + /// uuid.to_simple().encode_lower(&mut Uuid::encode_buffer()), + /// "936da01f9abd4d9d80c702af85c822a8" + /// ); + /// + /// // the buffer is mutated directly, and trailing contents remains + /// let mut buf = [b'!'; 36]; + /// assert_eq!( + /// uuid.to_simple().encode_lower(&mut buf), + /// "936da01f9abd4d9d80c702af85c822a8" + /// ); + /// assert_eq!( + /// &buf as &[_], + /// b"936da01f9abd4d9d80c702af85c822a8!!!!" as &[_] + /// ); + /// + /// Ok(()) + /// } + /// ``` + /// */ + pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { + encode(buffer, 0, &self.0, false, false) + } + + /// Writes the [`Uuid`] as an upper-case simple string to `buffer`, + /// and returns the subslice of the buffer that contains the encoded UUID. + /// + /// [`Uuid`]: ../struct.Uuid.html + /// + /// # Panics + /// + /// Panics if the buffer is not large enough: it must have length at least + /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a + /// sufficiently-large temporary buffer. + /// + /// [`LENGTH`]: #associatedconstant.LENGTH + /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer + /// + /// # Examples + /// + /// ```rust + /// use uuid::Uuid; + /// + /// fn main() -> Result<(), uuid::Error> { + /// let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8")?; + /// + /// // the encoded portion is returned + /// assert_eq!( + /// uuid.to_simple().encode_upper(&mut Uuid::encode_buffer()), + /// "936DA01F9ABD4D9D80C702AF85C822A8" + /// ); + /// + /// // the buffer is mutated directly, and trailing contents remains + /// let mut buf = [b'!'; 36]; + /// assert_eq!( + /// uuid.to_simple().encode_upper(&mut buf), + /// "936DA01F9ABD4D9D80C702AF85C822A8" + /// ); + /// assert_eq!( + /// &buf as &[_], + /// b"936DA01F9ABD4D9D80C702AF85C822A8!!!!" as &[_] + /// ); + /// + /// Ok(()) + /// } + /// ``` + /// */ + pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { + encode(buffer, 0, &self.0, false, true) + } +} + +impl<'a> SimpleRef<'a> { + /// The length of a simple [`Uuid`] string. + /// + /// [`Uuid`]: ../struct.Uuid.html + pub const LENGTH: usize = 32; + + /// Creates a [`SimpleRef`] from a [`Uuid`] reference. + /// + /// [`Uuid`]: ../struct.Uuid.html + /// [`SimpleRef`]: struct.SimpleRef.html + pub const fn from_uuid_ref(uuid: &'a Uuid) -> Self { + SimpleRef(uuid) + } + + /// Writes the [`Uuid`] as a lower-case simple string to `buffer`, + /// and returns the subslice of the buffer that contains the encoded UUID. + /// + /// This is slightly more efficient than using the formatting + /// infrastructure as it avoids virtual calls, and may avoid + /// double buffering. + /// + /// [`Uuid`]: ../struct.Uuid.html + /// + /// # Panics + /// + /// Panics if the buffer is not large enough: it must have length at least + /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a + /// sufficiently-large temporary buffer. + /// + /// [`LENGTH`]: #associatedconstant.LENGTH + /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer + /// + /// # Examples + /// + /// ```rust + /// use uuid::Uuid; + /// + /// fn main() -> Result<(), uuid::Error> { + /// let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8")?; + /// + /// // the encoded portion is returned + /// assert_eq!( + /// uuid.to_simple().encode_lower(&mut Uuid::encode_buffer()), + /// "936da01f9abd4d9d80c702af85c822a8" + /// ); + /// + /// // the buffer is mutated directly, and trailing contents remains + /// let mut buf = [b'!'; 36]; + /// assert_eq!( + /// uuid.to_simple().encode_lower(&mut buf), + /// "936da01f9abd4d9d80c702af85c822a8" + /// ); + /// assert_eq!( + /// &buf as &[_], + /// b"936da01f9abd4d9d80c702af85c822a8!!!!" as &[_] + /// ); + /// + /// Ok(()) + /// } + /// ``` + /// */ + pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { + encode(buffer, 0, self.0, false, false) + } + + /// Writes the [`Uuid`] as an upper-case simple string to `buffer`, + /// and returns the subslice of the buffer that contains the encoded UUID. + /// + /// [`Uuid`]: ../struct.Uuid.html + /// + /// # Panics + /// + /// Panics if the buffer is not large enough: it must have length at least + /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a + /// sufficiently-large temporary buffer. + /// + /// [`LENGTH`]: #associatedconstant.LENGTH + /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer + /// + /// # Examples + /// + /// ```rust + /// use uuid::Uuid; + /// + /// fn main() -> Result<(), uuid::Error> { + /// let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8")?; + /// + /// // the encoded portion is returned + /// assert_eq!( + /// uuid.to_simple().encode_upper(&mut Uuid::encode_buffer()), + /// "936DA01F9ABD4D9D80C702AF85C822A8" + /// ); + /// + /// // the buffer is mutated directly, and trailing contents remains + /// let mut buf = [b'!'; 36]; + /// assert_eq!( + /// uuid.to_simple().encode_upper(&mut buf), + /// "936DA01F9ABD4D9D80C702AF85C822A8" + /// ); + /// assert_eq!( + /// &buf as &[_], + /// b"936DA01F9ABD4D9D80C702AF85C822A8!!!!" as &[_] + /// ); + /// + /// Ok(()) + /// } + /// ``` + /// */ + pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { + encode(buffer, 0, self.0, false, true) + } +} + +impl Urn { + /// The length of a URN [`Uuid`] string. + /// + /// [`Uuid`]: ../struct.Uuid.html + pub const LENGTH: usize = 45; + + /// Creates a [`Urn`] from a [`Uuid`]. + /// + /// [`Uuid`]: ../struct.Uuid.html + /// [`Urn`]: struct.Urn.html + pub const fn from_uuid(uuid: Uuid) -> Self { + Urn(uuid) + } + + /// Writes the [`Uuid`] as a lower-case URN string to + /// `buffer`, and returns the subslice of the buffer that contains the + /// encoded UUID. + /// + /// This is slightly more efficient than using the formatting + /// infrastructure as it avoids virtual calls, and may avoid + /// double buffering. + /// + /// [`Uuid`]: ../struct.Uuid.html + /// + /// # Panics + /// + /// Panics if the buffer is not large enough: it must have length at least + /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a + /// sufficiently-large temporary buffer. + /// + /// [`LENGTH`]: #associatedconstant.LENGTH + /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer + /// + /// # Examples + /// + /// ```rust + /// use uuid::Uuid; + /// + /// fn main() -> Result<(), uuid::Error> { + /// let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8")?; + /// + /// // the encoded portion is returned + /// assert_eq!( + /// uuid.to_urn().encode_lower(&mut Uuid::encode_buffer()), + /// "urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8" + /// ); + /// + /// // the buffer is mutated directly, and trailing contents remains + /// let mut buf = [b'!'; 49]; + /// uuid.to_urn().encode_lower(&mut buf); + /// assert_eq!( + /// uuid.to_urn().encode_lower(&mut buf), + /// "urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8" + /// ); + /// assert_eq!( + /// &buf as &[_], + /// b"urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8!!!!" as &[_] + /// ); + /// + /// Ok(()) + /// } + /// ``` + /// */ + pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { + buffer[..9].copy_from_slice(b"urn:uuid:"); + encode(buffer, 9, &self.0, true, false) + } + + /// Writes the [`Uuid`] as an upper-case URN string to + /// `buffer`, and returns the subslice of the buffer that contains the + /// encoded UUID. + /// + /// This is slightly more efficient than using the formatting + /// infrastructure as it avoids virtual calls, and may avoid + /// double buffering. + /// + /// [`Uuid`]: ../struct.Uuid.html + /// + /// # Panics + /// + /// Panics if the buffer is not large enough: it must have length at least + /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a + /// sufficiently-large temporary buffer. + /// + /// [`LENGTH`]: #associatedconstant.LENGTH + /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer + /// + /// # Examples + /// + /// ```rust + /// use uuid::Uuid; + /// + /// fn main() -> Result<(), uuid::Error> { + /// let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8")?; + /// + /// // the encoded portion is returned + /// assert_eq!( + /// uuid.to_urn().encode_upper(&mut Uuid::encode_buffer()), + /// "urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8" + /// ); + /// + /// // the buffer is mutated directly, and trailing contents remains + /// let mut buf = [b'!'; 49]; + /// assert_eq!( + /// uuid.to_urn().encode_upper(&mut buf), + /// "urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8" + /// ); + /// assert_eq!( + /// &buf as &[_], + /// b"urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8!!!!" as &[_] + /// ); + /// + /// Ok(()) + /// } + /// ``` + /// */ + pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { + buffer[..9].copy_from_slice(b"urn:uuid:"); + encode(buffer, 9, &self.0, true, true) + } +} + +impl<'a> UrnRef<'a> { + /// The length of a URN [`Uuid`] string. + /// + /// [`Uuid`]: ../struct.Uuid.html + pub const LENGTH: usize = 45; + + /// Creates a [`UrnRef`] from a [`Uuid`] reference. + /// + /// [`Uuid`]: ../struct.Uuid.html + /// [`UrnRef`]: struct.UrnRef.html + pub const fn from_uuid_ref(uuid: &'a Uuid) -> Self { + UrnRef(&uuid) + } + + /// Writes the [`Uuid`] as a lower-case URN string to + /// `buffer`, and returns the subslice of the buffer that contains the + /// encoded UUID. + /// + /// This is slightly more efficient than using the formatting + /// infrastructure as it avoids virtual calls, and may avoid + /// double buffering. + /// + /// [`Uuid`]: ../struct.Uuid.html + /// + /// # Panics + /// + /// Panics if the buffer is not large enough: it must have length at least + /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a + /// sufficiently-large temporary buffer. + /// + /// [`LENGTH`]: #associatedconstant.LENGTH + /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer + /// + /// # Examples + /// + /// ```rust + /// use uuid::Uuid; + /// + /// fn main() -> Result<(), uuid::Error> { + /// let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8")?; + /// + /// // the encoded portion is returned + /// assert_eq!( + /// uuid.to_urn().encode_lower(&mut Uuid::encode_buffer()), + /// "urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8" + /// ); + /// + /// // the buffer is mutated directly, and trailing contents remains + /// let mut buf = [b'!'; 49]; + /// uuid.to_urn().encode_lower(&mut buf); + /// assert_eq!( + /// uuid.to_urn().encode_lower(&mut buf), + /// "urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8" + /// ); + /// assert_eq!( + /// &buf as &[_], + /// b"urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8!!!!" as &[_] + /// ); + /// + /// Ok(()) + /// } + /// ``` + /// */ + pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { + buffer[..9].copy_from_slice(b"urn:uuid:"); + encode(buffer, 9, self.0, true, false) + } + + /// Writes the [`Uuid`] as an upper-case URN string to + /// `buffer`, and returns the subslice of the buffer that contains the + /// encoded UUID. + /// + /// This is slightly more efficient than using the formatting + /// infrastructure as it avoids virtual calls, and may avoid + /// double buffering. + /// + /// [`Uuid`]: ../struct.Uuid.html + /// + /// # Panics + /// + /// Panics if the buffer is not large enough: it must have length at least + /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a + /// sufficiently-large temporary buffer. + /// + /// [`LENGTH`]: #associatedconstant.LENGTH + /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer + /// + /// # Examples + /// + /// ```rust + /// use uuid::Uuid; + /// + /// fn main() -> Result<(), uuid::Error> { + /// let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8")?; + /// + /// // the encoded portion is returned + /// assert_eq!( + /// uuid.to_urn().encode_upper(&mut Uuid::encode_buffer()), + /// "urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8" + /// ); + /// + /// // the buffer is mutated directly, and trailing contents remains + /// let mut buf = [b'!'; 49]; + /// assert_eq!( + /// uuid.to_urn().encode_upper(&mut buf), + /// "urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8" + /// ); + /// assert_eq!( + /// &buf as &[_], + /// b"urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8!!!!" as &[_] + /// ); + /// + /// Ok(()) + /// } + /// ``` + /// */ + pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { + buffer[..9].copy_from_slice(b"urn:uuid:"); + encode(buffer, 9, self.0, true, true) + } +} + +macro_rules! impl_adapter_traits { + ($($T:ident<$($a:lifetime),*>),+) => {$( + impl<$($a),*> fmt::Display for $T<$($a),*> { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::LowerHex::fmt(self, f) + } + } + + impl<$($a),*> fmt::LowerHex for $T<$($a),*> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // TODO: Self doesn't work https://github.com/rust-lang/rust/issues/52808 + f.write_str(self.encode_lower(&mut [0; $T::LENGTH])) + } + } + + impl<$($a),*> fmt::UpperHex for $T<$($a),*> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // TODO: Self doesn't work https://github.com/rust-lang/rust/issues/52808 + f.write_str(self.encode_upper(&mut [0; $T::LENGTH])) + } + } + + impl_adapter_from!($T<$($a),*>); + )+} +} + +macro_rules! impl_adapter_from { + ($T:ident<>) => { + impl From for $T { + #[inline] + fn from(f: Uuid) -> Self { + $T::from_uuid(f) + } + } + }; + ($T:ident<$a:lifetime>) => { + impl<$a> From<&$a Uuid> for $T<$a> { + #[inline] + fn from(f: &$a Uuid) -> Self { + $T::from_uuid_ref(f) + } + } + }; +} + +impl_adapter_traits! { + Hyphenated<>, + HyphenatedRef<'a>, + Simple<>, + SimpleRef<'a>, + Urn<>, + UrnRef<'a> +} + +#[cfg(test)] +mod tests { + use crate::prelude::*; + + #[test] + fn hyphenated_trailing() { + let mut buf = [b'x'; 100]; + let len = Uuid::nil().to_hyphenated().encode_lower(&mut buf).len(); + assert_eq!(len, super::Hyphenated::LENGTH); + assert!(buf[len..].iter().all(|x| *x == b'x')); + } + + #[test] + fn hyphenated_ref_trailing() { + let mut buf = [b'x'; 100]; + let len = Uuid::nil().to_hyphenated().encode_lower(&mut buf).len(); + assert_eq!(len, super::HyphenatedRef::LENGTH); + assert!(buf[len..].iter().all(|x| *x == b'x')); + } + + #[test] + fn simple_trailing() { + let mut buf = [b'x'; 100]; + let len = Uuid::nil().to_simple().encode_lower(&mut buf).len(); + assert_eq!(len, super::Simple::LENGTH); + assert!(buf[len..].iter().all(|x| *x == b'x')); + } + + #[test] + fn simple_ref_trailing() { + let mut buf = [b'x'; 100]; + let len = Uuid::nil().to_simple().encode_lower(&mut buf).len(); + assert_eq!(len, super::SimpleRef::LENGTH); + assert!(buf[len..].iter().all(|x| *x == b'x')); + } + + #[test] + fn urn_trailing() { + let mut buf = [b'x'; 100]; + let len = Uuid::nil().to_urn().encode_lower(&mut buf).len(); + assert_eq!(len, super::Urn::LENGTH); + assert!(buf[len..].iter().all(|x| *x == b'x')); + } + + #[test] + fn urn_ref_trailing() { + let mut buf = [b'x'; 100]; + let len = Uuid::nil().to_urn().encode_lower(&mut buf).len(); + assert_eq!(len, super::UrnRef::LENGTH); + assert!(buf[len..].iter().all(|x| *x == b'x')); + } + + #[test] + #[should_panic] + fn hyphenated_too_small() { + Uuid::nil().to_hyphenated().encode_lower(&mut [0; 35]); + } + + #[test] + #[should_panic] + fn hyphenated_ref_too_small() { + Uuid::nil().to_hyphenated_ref().encode_lower(&mut [0; 35]); + } + + #[test] + #[should_panic] + fn simple_too_small() { + Uuid::nil().to_simple().encode_lower(&mut [0; 31]); + } + #[test] + #[should_panic] + fn simple_ref_too_small() { + Uuid::nil().to_simple_ref().encode_lower(&mut [0; 31]); + } + #[test] + #[should_panic] + fn urn_too_small() { + Uuid::nil().to_urn().encode_lower(&mut [0; 44]); + } + #[test] + #[should_panic] + fn urn_ref_too_small() { + Uuid::nil().to_urn_ref().encode_lower(&mut [0; 44]); + } +} diff --git a/vendor/uuid/src/builder/error.rs b/vendor/uuid/src/builder/error.rs new file mode 100644 index 000000000..ec7c2ac88 --- /dev/null +++ b/vendor/uuid/src/builder/error.rs @@ -0,0 +1,52 @@ +use crate::std::fmt; + +/// The error that can occur when creating a [`Uuid`]. +/// +/// [`Uuid`]: struct.Uuid.html +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub(crate) struct Error { + expected: usize, + found: usize, +} + +impl Error { + /// The expected number of bytes. + #[inline] + const fn expected(&self) -> usize { + self.expected + } + + /// The number of bytes found. + #[inline] + const fn found(&self) -> usize { + self.found + } + + /// Create a new [`UuidError`]. + /// + /// [`UuidError`]: struct.UuidError.html + #[inline] + pub(crate) const fn new(expected: usize, found: usize) -> Self { + Error { expected, found } + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "invalid bytes length: expected {}, found {}", + self.expected(), + self.found() + ) + } +} + +#[cfg(feature = "std")] +mod std_support { + use super::*; + + use crate::std::error; + + impl error::Error for Error {} +} diff --git a/vendor/uuid/src/builder/mod.rs b/vendor/uuid/src/builder/mod.rs new file mode 100644 index 000000000..43609642c --- /dev/null +++ b/vendor/uuid/src/builder/mod.rs @@ -0,0 +1,473 @@ +// 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. + +//! A Builder type for [`Uuid`]s. +//! +//! [`Uuid`]: ../struct.Uuid.html + +mod error; +pub(crate) use self::error::Error; + +use crate::prelude::*; + +impl Uuid { + /// The 'nil UUID'. + /// + /// The nil UUID is special form of UUID that is specified to have all + /// 128 bits set to zero, as defined in [IETF RFC 4122 Section 4.1.7][RFC]. + /// + /// [RFC]: https://tools.ietf.org/html/rfc4122.html#section-4.1.7 + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use uuid::Uuid; + /// + /// let uuid = Uuid::nil(); + /// + /// assert_eq!( + /// uuid.to_hyphenated().to_string(), + /// "00000000-0000-0000-0000-000000000000" + /// ); + /// ``` + pub const fn nil() -> Self { + Uuid::from_bytes([0; 16]) + } + + /// Creates a UUID from four field values in big-endian order. + /// + /// # Errors + /// + /// This function will return an error if `d4`'s length is not 8 bytes. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use uuid::Uuid; + /// + /// let d4 = [12, 3, 9, 56, 54, 43, 8, 9]; + /// + /// let uuid = Uuid::from_fields(42, 12, 5, &d4); + /// let uuid = uuid.map(|uuid| uuid.to_hyphenated().to_string()); + /// + /// let expected_uuid = + /// Ok(String::from("0000002a-000c-0005-0c03-0938362b0809")); + /// + /// assert_eq!(expected_uuid, uuid); + /// ``` + pub fn from_fields( + d1: u32, + d2: u16, + d3: u16, + d4: &[u8], + ) -> Result { + const D4_LEN: usize = 8; + + let len = d4.len(); + + if len != D4_LEN { + Err(Error::new(D4_LEN, len))?; + } + + Ok(Uuid::from_bytes([ + (d1 >> 24) as u8, + (d1 >> 16) as u8, + (d1 >> 8) as u8, + d1 as u8, + (d2 >> 8) as u8, + d2 as u8, + (d3 >> 8) as u8, + d3 as u8, + d4[0], + d4[1], + d4[2], + d4[3], + d4[4], + d4[5], + d4[6], + d4[7], + ])) + } + + /// Creates a UUID from four field values in little-endian order. + /// + /// The bytes in the `d1`, `d2` and `d3` fields will + /// be converted into big-endian order. + /// + /// # Examples + /// + /// ``` + /// use uuid::Uuid; + /// + /// let d1 = 0xAB3F1097u32; + /// let d2 = 0x501Eu16; + /// let d3 = 0xB736u16; + /// let d4 = [12, 3, 9, 56, 54, 43, 8, 9]; + /// + /// let uuid = Uuid::from_fields_le(d1, d2, d3, &d4); + /// let uuid = uuid.map(|uuid| uuid.to_hyphenated().to_string()); + /// + /// let expected_uuid = + /// Ok(String::from("97103fab-1e50-36b7-0c03-0938362b0809")); + /// + /// assert_eq!(expected_uuid, uuid); + /// ``` + pub fn from_fields_le( + d1: u32, + d2: u16, + d3: u16, + d4: &[u8], + ) -> Result { + const D4_LEN: usize = 8; + + let len = d4.len(); + + if len != D4_LEN { + Err(Error::new(D4_LEN, len))?; + } + + Ok(Uuid::from_bytes([ + d1 as u8, + (d1 >> 8) as u8, + (d1 >> 16) as u8, + (d1 >> 24) as u8, + (d2) as u8, + (d2 >> 8) as u8, + d3 as u8, + (d3 >> 8) as u8, + d4[0], + d4[1], + d4[2], + d4[3], + d4[4], + d4[5], + d4[6], + d4[7], + ])) + } + + /// Creates a UUID from a 128bit value in big-endian order. + pub const fn from_u128(v: u128) -> Self { + Uuid::from_bytes([ + (v >> 120) as u8, + (v >> 112) as u8, + (v >> 104) as u8, + (v >> 96) as u8, + (v >> 88) as u8, + (v >> 80) as u8, + (v >> 72) as u8, + (v >> 64) as u8, + (v >> 56) as u8, + (v >> 48) as u8, + (v >> 40) as u8, + (v >> 32) as u8, + (v >> 24) as u8, + (v >> 16) as u8, + (v >> 8) as u8, + v as u8, + ]) + } + + /// Creates a UUID from a 128bit value in little-endian order. + pub const fn from_u128_le(v: u128) -> Self { + Uuid::from_bytes([ + v as u8, + (v >> 8) as u8, + (v >> 16) as u8, + (v >> 24) as u8, + (v >> 32) as u8, + (v >> 40) as u8, + (v >> 48) as u8, + (v >> 56) as u8, + (v >> 64) as u8, + (v >> 72) as u8, + (v >> 80) as u8, + (v >> 88) as u8, + (v >> 96) as u8, + (v >> 104) as u8, + (v >> 112) as u8, + (v >> 120) as u8, + ]) + } + + /// Creates a UUID using the supplied big-endian bytes. + /// + /// # Errors + /// + /// This function will return an error if `b` has any length other than 16. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use uuid::Uuid; + /// + /// let bytes = [4, 54, 67, 12, 43, 2, 98, 76, 32, 50, 87, 5, 1, 33, 43, 87]; + /// + /// let uuid = Uuid::from_slice(&bytes); + /// let uuid = uuid.map(|uuid| uuid.to_hyphenated().to_string()); + /// + /// let expected_uuid = + /// Ok(String::from("0436430c-2b02-624c-2032-570501212b57")); + /// + /// assert_eq!(expected_uuid, uuid); + /// ``` + /// + /// An incorrect number of bytes: + /// + /// ``` + /// use uuid::Uuid; + /// + /// let bytes = [4, 54, 67, 12, 43, 2, 98, 76]; + /// + /// let uuid = Uuid::from_slice(&bytes); + /// + /// assert!(uuid.is_err()); + /// ``` + pub fn from_slice(b: &[u8]) -> Result { + const BYTES_LEN: usize = 16; + + let len = b.len(); + + if len != BYTES_LEN { + Err(Error::new(BYTES_LEN, len))?; + } + + let mut bytes: Bytes = [0; 16]; + bytes.copy_from_slice(b); + Ok(Uuid::from_bytes(bytes)) + } + + /// Creates a UUID using the supplied big-endian bytes. + pub const fn from_bytes(bytes: Bytes) -> Uuid { + Uuid(bytes) + } +} + +/// 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(); +/// ``` +// TODO: remove in 1.0.0 +#[allow(dead_code)] +#[deprecated] +pub type Builder = crate::Builder; + +impl crate::Builder { + /// Creates a `Builder` using the supplied big-endian bytes. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let bytes: uuid::Bytes = [ + /// 70, 235, 208, 238, 14, 109, 67, 201, 185, 13, 204, 195, 90, 145, 63, 62, + /// ]; + /// + /// let mut builder = uuid::Builder::from_bytes(bytes); + /// let uuid = builder.build().to_hyphenated().to_string(); + /// + /// let expected_uuid = String::from("46ebd0ee-0e6d-43c9-b90d-ccc35a913f3e"); + /// + /// assert_eq!(expected_uuid, uuid); + /// ``` + /// + /// An incorrect number of bytes: + /// + /// ```compile_fail + /// let bytes: uuid::Bytes = [4, 54, 67, 12, 43, 2, 98, 76]; // doesn't compile + /// + /// let uuid = uuid::Builder::from_bytes(bytes); + /// ``` + pub const fn from_bytes(b: Bytes) -> Self { + Builder(b) + } + + /// Creates a `Builder` using the supplied big-endian bytes. + /// + /// # Errors + /// + /// This function will return an error if `b` has any length other than 16. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let bytes = [4, 54, 67, 12, 43, 2, 98, 76, 32, 50, 87, 5, 1, 33, 43, 87]; + /// + /// let builder = uuid::Builder::from_slice(&bytes); + /// let uuid = + /// builder.map(|mut builder| builder.build().to_hyphenated().to_string()); + /// + /// let expected_uuid = + /// Ok(String::from("0436430c-2b02-624c-2032-570501212b57")); + /// + /// assert_eq!(expected_uuid, uuid); + /// ``` + /// + /// An incorrect number of bytes: + /// + /// ``` + /// let bytes = [4, 54, 67, 12, 43, 2, 98, 76]; + /// + /// let builder = uuid::Builder::from_slice(&bytes); + /// + /// assert!(builder.is_err()); + /// ``` + pub fn from_slice(b: &[u8]) -> Result { + const BYTES_LEN: usize = 16; + + let len = b.len(); + + if len != BYTES_LEN { + Err(Error::new(BYTES_LEN, len))?; + } + + let mut bytes: crate::Bytes = [0; 16]; + bytes.copy_from_slice(b); + Ok(Self::from_bytes(bytes)) + } + + /// Creates a `Builder` from four big-endian field values. + /// + /// # Errors + /// + /// This function will return an error if `d4`'s length is not 8 bytes. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let d4 = [12, 3, 9, 56, 54, 43, 8, 9]; + /// + /// let builder = uuid::Builder::from_fields(42, 12, 5, &d4); + /// let uuid = + /// builder.map(|mut builder| builder.build().to_hyphenated().to_string()); + /// + /// let expected_uuid = + /// Ok(String::from("0000002a-000c-0005-0c03-0938362b0809")); + /// + /// assert_eq!(expected_uuid, uuid); + /// ``` + /// + /// An invalid length: + /// + /// ``` + /// let d4 = [12]; + /// + /// let builder = uuid::Builder::from_fields(42, 12, 5, &d4); + /// + /// assert!(builder.is_err()); + /// ``` + pub fn from_fields( + d1: u32, + d2: u16, + d3: u16, + d4: &[u8], + ) -> Result { + Uuid::from_fields(d1, d2, d3, d4).map(|uuid| { + let bytes = *uuid.as_bytes(); + + crate::Builder::from_bytes(bytes) + }) + } + + /// Creates a `Builder` from a big-endian 128bit value. + pub fn from_u128(v: u128) -> Self { + crate::Builder::from_bytes(*Uuid::from_u128(v).as_bytes()) + } + + /// Creates a `Builder` with an initial [`Uuid::nil`]. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use uuid::Builder; + /// + /// let mut builder = Builder::nil(); + /// + /// assert_eq!( + /// builder.build().to_hyphenated().to_string(), + /// "00000000-0000-0000-0000-000000000000" + /// ); + /// ``` + pub const fn nil() -> Self { + Builder([0; 16]) + } + + /// Specifies the variant of the UUID. + pub fn set_variant(&mut self, v: crate::Variant) -> &mut Self { + let byte = self.0[8]; + + self.0[8] = match v { + crate::Variant::NCS => byte & 0x7f, + crate::Variant::RFC4122 => (byte & 0x3f) | 0x80, + crate::Variant::Microsoft => (byte & 0x1f) | 0xc0, + crate::Variant::Future => (byte & 0x1f) | 0xe0, + }; + + self + } + + /// Specifies the version number of the UUID. + pub fn set_version(&mut self, v: crate::Version) -> &mut Self { + self.0[6] = (self.0[6] & 0x0f) | ((v as u8) << 4); + + self + } + + /// Hands over the internal constructed [`Uuid`]. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use uuid::Builder; + /// + /// let uuid = Builder::nil().build(); + /// + /// assert_eq!( + /// uuid.to_hyphenated().to_string(), + /// "00000000-0000-0000-0000-000000000000" + /// ); + /// ``` + /// + /// [`Uuid`]: struct.Uuid.html + pub fn build(&mut self) -> Uuid { + Uuid::from_bytes(self.0) + } +} diff --git a/vendor/uuid/src/error.rs b/vendor/uuid/src/error.rs new file mode 100644 index 000000000..59f3f5e13 --- /dev/null +++ b/vendor/uuid/src/error.rs @@ -0,0 +1,79 @@ +use crate::std::fmt; +use crate::{builder, parser}; + +/// A general error that can occur when working with UUIDs. +// TODO: improve the doc +// BODY: This detail should be fine for initial merge +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub struct Error(Inner); + +// TODO: write tests for Error +// BODY: not immediately blocking, but should be covered for 1.0 +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +enum Inner { + /// An error occurred while handling [`Uuid`] bytes. + /// + /// See [`BytesError`] + /// + /// [`BytesError`]: struct.BytesError.html + /// [`Uuid`]: struct.Uuid.html + Build(builder::Error), + + /// An error occurred while parsing a [`Uuid`] string. + /// + /// See [`parser::ParseError`] + /// + /// [`parser::ParseError`]: parser/enum.ParseError.html + /// [`Uuid`]: struct.Uuid.html + Parser(parser::Error), +} + +impl From for Error { + fn from(err: builder::Error) -> Self { + Error(Inner::Build(err)) + } +} + +impl From for Error { + fn from(err: parser::Error) -> Self { + Error(Inner::Parser(err)) + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.0 { + Inner::Build(ref err) => fmt::Display::fmt(&err, f), + Inner::Parser(ref err) => fmt::Display::fmt(&err, f), + } + } +} + +#[cfg(feature = "std")] +mod std_support { + use super::*; + use crate::std::error; + + impl error::Error for Error { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + match self.0 { + Inner::Build(ref err) => Some(err), + Inner::Parser(ref err) => Some(err), + } + } + } +} + +#[cfg(test)] +mod test_util { + use super::*; + + impl Error { + pub(crate) fn expect_parser(self) -> parser::Error { + match self.0 { + Inner::Parser(err) => err, + _ => panic!("expected a `parser::Error` variant"), + } + } + } +} 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)); + } +} diff --git a/vendor/uuid/src/parser/error.rs b/vendor/uuid/src/parser/error.rs new file mode 100644 index 000000000..01d76e810 --- /dev/null +++ b/vendor/uuid/src/parser/error.rs @@ -0,0 +1,149 @@ +use crate::std::fmt; + +/// An error that can occur while parsing a [`Uuid`] string. +/// +/// [`Uuid`]: ../struct.Uuid.html +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +#[allow(clippy::enum_variant_names)] +pub(crate) enum Error { + /// Invalid character in the [`Uuid`] string. + /// + /// [`Uuid`]: ../struct.Uuid.html + InvalidCharacter { + /// The expected characters. + expected: &'static str, + /// The invalid character found. + found: char, + /// The invalid character position. + index: usize, + /// Indicates the [`Uuid`] starts with `urn:uuid:`. + /// + /// This is a special case for [`Urn`] adapter parsing. + /// + /// [`Uuid`]: ../Uuid.html + urn: UrnPrefix, + }, + /// Invalid number of segments in the [`Uuid`] string. + /// + /// [`Uuid`]: ../struct.Uuid.html + InvalidGroupCount { + /// The expected number of segments. + // TODO: explain multiple segment count. + // BODY: Parsers can expect a range of Uuid segment count. + // This needs to be expanded on. + expected: ExpectedLength, + /// The number of segments found. + found: usize, + }, + /// Invalid length of a segment in a [`Uuid`] string. + /// + /// [`Uuid`]: ../struct.Uuid.html + InvalidGroupLength { + /// The expected length of the segment. + expected: ExpectedLength, + /// The length of segment found. + found: usize, + /// The segment with invalid length. + group: usize, + }, + /// Invalid length of the [`Uuid`] string. + /// + /// [`Uuid`]: ../struct.Uuid.html + InvalidLength { + /// The expected length(s). + // TODO: explain multiple lengths. + // BODY: Parsers can expect a range of Uuid lenghts. + // This needs to be expanded on. + expected: ExpectedLength, + /// The invalid length found. + found: usize, + }, +} + +/// The expected length. +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub(crate) enum ExpectedLength { + /// Expected any one of the given values. + Any(&'static [usize]), + /// Expected the given value. + Exact(usize), +} + +/// Urn prefix value. +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub(crate) enum UrnPrefix { + /// The `urn:uuid:` prefix should optionally provided. + Optional, +} + +impl Error { + fn _description(&self) -> &str { + match *self { + Error::InvalidCharacter { .. } => "invalid character", + Error::InvalidGroupCount { .. } => "invalid number of groups", + Error::InvalidGroupLength { .. } => "invalid group length", + Error::InvalidLength { .. } => "invalid length", + } + } +} + +impl fmt::Display for ExpectedLength { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + ExpectedLength::Any(crits) => write!(f, "one of {:?}", crits), + ExpectedLength::Exact(crit) => write!(f, "{}", crit), + } + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}: ", self._description())?; + + match *self { + Error::InvalidCharacter { + expected, + found, + index, + urn, + } => { + let urn_str = match urn { + UrnPrefix::Optional => { + " an optional prefix of `urn:uuid:` followed by" + } + }; + + write!( + f, + "expected{} {}, found {} at {}", + urn_str, expected, found, index + ) + } + Error::InvalidGroupCount { + ref expected, + found, + } => write!(f, "expected {}, found {}", expected, found), + Error::InvalidGroupLength { + ref expected, + found, + group, + } => write!( + f, + "expected {}, found {} in group {}", + expected, found, group, + ), + Error::InvalidLength { + ref expected, + found, + } => write!(f, "expected {}, found {}", expected, found), + } + } +} + +#[cfg(feature = "std")] +mod std_support { + use super::*; + use crate::std::error; + + impl error::Error for Error {} +} diff --git a/vendor/uuid/src/parser/mod.rs b/vendor/uuid/src/parser/mod.rs new file mode 100644 index 000000000..a80f696b0 --- /dev/null +++ b/vendor/uuid/src/parser/mod.rs @@ -0,0 +1,447 @@ +// 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. + +//! [`Uuid`] parsing constructs and utilities. +//! +//! [`Uuid`]: ../struct.Uuid.html + +pub(crate) mod error; +pub(crate) use self::error::Error; + +use crate::{adapter, Uuid}; + +/// Check if the length matches any of the given criteria lengths. +fn len_matches_any(len: usize, crits: &[usize]) -> bool { + for crit in crits { + if len == *crit { + return true; + } + } + + false +} + +/// Check if the length matches any criteria lengths in the given range +/// (inclusive). +#[allow(dead_code)] +fn len_matches_range(len: usize, min: usize, max: usize) -> bool { + for crit in min..=max { + if len == crit { + return true; + } + } + + false +} + +// Accumulated length of each hyphenated group in hex digits. +const ACC_GROUP_LENS: [usize; 5] = [8, 12, 16, 20, 32]; + +// Length of each hyphenated group in hex digits. +const GROUP_LENS: [usize; 5] = [8, 4, 4, 4, 12]; + +impl Uuid { + /// Parses a `Uuid` from a string of hexadecimal digits with optional + /// hyphens. + /// + /// Any of the formats generated by this module (simple, hyphenated, urn) + /// are supported by this parsing function. + pub fn parse_str(mut input: &str) -> Result { + // Ensure length is valid for any of the supported formats + let len = input.len(); + + if len == adapter::Urn::LENGTH && input.starts_with("urn:uuid:") { + input = &input[9..]; + } else if !len_matches_any( + len, + &[adapter::Hyphenated::LENGTH, adapter::Simple::LENGTH], + ) { + Err(Error::InvalidLength { + expected: error::ExpectedLength::Any(&[ + adapter::Hyphenated::LENGTH, + adapter::Simple::LENGTH, + ]), + found: len, + })?; + } + + // `digit` counts only hexadecimal digits, `i_char` counts all chars. + let mut digit = 0; + let mut group = 0; + let mut acc = 0; + let mut buffer = [0u8; 16]; + + for (i_char, chr) in input.bytes().enumerate() { + if digit as usize >= adapter::Simple::LENGTH && group != 4 { + if group == 0 { + Err(Error::InvalidLength { + expected: error::ExpectedLength::Any(&[ + adapter::Hyphenated::LENGTH, + adapter::Simple::LENGTH, + ]), + found: len, + })?; + } + + Err(Error::InvalidGroupCount { + expected: error::ExpectedLength::Any(&[1, 5]), + found: group + 1, + })?; + } + + if digit % 2 == 0 { + // First digit of the byte. + match chr { + // Calulate upper half. + b'0'..=b'9' => acc = chr - b'0', + b'a'..=b'f' => acc = chr - b'a' + 10, + b'A'..=b'F' => acc = chr - b'A' + 10, + // Found a group delimiter + b'-' => { + // TODO: remove the u8 cast + // BODY: this only needed until we switch to + // ParseError + if ACC_GROUP_LENS[group] as u8 != digit { + // Calculate how many digits this group consists of + // in the input. + let found = if group > 0 { + // TODO: remove the u8 cast + // BODY: this only needed until we switch to + // ParseError + digit - ACC_GROUP_LENS[group - 1] as u8 + } else { + digit + }; + + Err(Error::InvalidGroupLength { + expected: error::ExpectedLength::Exact( + GROUP_LENS[group], + ), + found: found as usize, + group, + })?; + } + // Next group, decrement digit, it is incremented again + // at the bottom. + group += 1; + digit -= 1; + } + _ => { + Err(Error::InvalidCharacter { + expected: "0123456789abcdefABCDEF-", + found: input[i_char..].chars().next().unwrap(), + index: i_char, + urn: error::UrnPrefix::Optional, + })?; + } + } + } else { + // Second digit of the byte, shift the upper half. + acc *= 16; + match chr { + b'0'..=b'9' => acc += chr - b'0', + b'a'..=b'f' => acc += chr - b'a' + 10, + b'A'..=b'F' => acc += chr - b'A' + 10, + b'-' => { + // The byte isn't complete yet. + let found = if group > 0 { + // TODO: remove the u8 cast + // BODY: this only needed until we switch to + // ParseError + digit - ACC_GROUP_LENS[group - 1] as u8 + } else { + digit + }; + + Err(Error::InvalidGroupLength { + expected: error::ExpectedLength::Exact( + GROUP_LENS[group], + ), + found: found as usize, + group, + })?; + } + _ => { + Err(Error::InvalidCharacter { + expected: "0123456789abcdefABCDEF-", + found: input[i_char..].chars().next().unwrap(), + index: i_char, + urn: error::UrnPrefix::Optional, + })?; + } + } + buffer[(digit / 2) as usize] = acc; + } + digit += 1; + } + + // Now check the last group. + // TODO: remove the u8 cast + // BODY: this only needed until we switch to + // ParseError + if ACC_GROUP_LENS[4] as u8 != digit { + Err(Error::InvalidGroupLength { + expected: error::ExpectedLength::Exact(GROUP_LENS[4]), + found: (digit as usize - ACC_GROUP_LENS[3]), + group, + })?; + } + + Ok(Uuid::from_bytes(buffer)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{adapter, std::string::ToString, test_util}; + + #[test] + fn test_parse_uuid_v4() { + const EXPECTED_UUID_LENGTHS: error::ExpectedLength = + error::ExpectedLength::Any(&[ + adapter::Hyphenated::LENGTH, + adapter::Simple::LENGTH, + ]); + + const EXPECTED_GROUP_COUNTS: error::ExpectedLength = + error::ExpectedLength::Any(&[1, 5]); + + const EXPECTED_CHARS: &'static str = "0123456789abcdefABCDEF-"; + + // Invalid + assert_eq!( + Uuid::parse_str("").map_err(crate::Error::expect_parser), + Err(Error::InvalidLength { + expected: EXPECTED_UUID_LENGTHS, + found: 0, + }) + ); + + assert_eq!( + Uuid::parse_str("!").map_err(crate::Error::expect_parser), + Err(Error::InvalidLength { + expected: EXPECTED_UUID_LENGTHS, + found: 1 + }) + ); + + assert_eq!( + Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E45") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidLength { + expected: EXPECTED_UUID_LENGTHS, + found: 37, + }) + ); + + assert_eq!( + Uuid::parse_str("F9168C5E-CEB2-4faa-BBF-329BF39FA1E4") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidLength { + expected: EXPECTED_UUID_LENGTHS, + found: 35 + }) + ); + + assert_eq!( + Uuid::parse_str("F9168C5E-CEB2-4faa-BGBF-329BF39FA1E4") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidCharacter { + expected: EXPECTED_CHARS, + found: 'G', + index: 20, + urn: error::UrnPrefix::Optional, + }) + ); + + assert_eq!( + Uuid::parse_str("F9168C5E-CEB2F4faaFB6BFF329BF39FA1E4") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidGroupCount { + expected: EXPECTED_GROUP_COUNTS, + found: 2 + }) + ); + + assert_eq!( + Uuid::parse_str("F9168C5E-CEB2-4faaFB6BFF329BF39FA1E4") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidGroupCount { + expected: EXPECTED_GROUP_COUNTS, + found: 3, + }) + ); + + assert_eq!( + Uuid::parse_str("F9168C5E-CEB2-4faa-B6BFF329BF39FA1E4") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidGroupCount { + expected: EXPECTED_GROUP_COUNTS, + found: 4, + }) + ); + + assert_eq!( + Uuid::parse_str("F9168C5E-CEB2-4faa") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidLength { + expected: EXPECTED_UUID_LENGTHS, + found: 18, + }) + ); + + assert_eq!( + Uuid::parse_str("F9168C5E-CEB2-4faaXB6BFF329BF39FA1E4") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidCharacter { + expected: EXPECTED_CHARS, + found: 'X', + index: 18, + urn: error::UrnPrefix::Optional, + }) + ); + + assert_eq!( + Uuid::parse_str("F9168C5E-CEB-24fa-eB6BFF32-BF39FA1E4") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidGroupLength { + expected: error::ExpectedLength::Exact(4), + found: 3, + group: 1, + }) + ); + // (group, found, expecting) + // + assert_eq!( + Uuid::parse_str("01020304-1112-2122-3132-41424344") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidGroupLength { + expected: error::ExpectedLength::Exact(12), + found: 8, + group: 4, + }) + ); + + assert_eq!( + Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidLength { + expected: EXPECTED_UUID_LENGTHS, + found: 31, + }) + ); + + assert_eq!( + Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c88") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidLength { + expected: EXPECTED_UUID_LENGTHS, + found: 33, + }) + ); + + assert_eq!( + Uuid::parse_str("67e5504410b1426f9247bb680e5fe0cg8") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidLength { + expected: EXPECTED_UUID_LENGTHS, + found: 33, + }) + ); + + assert_eq!( + Uuid::parse_str("67e5504410b1426%9247bb680e5fe0c8") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidCharacter { + expected: EXPECTED_CHARS, + found: '%', + index: 15, + urn: error::UrnPrefix::Optional, + }) + ); + + assert_eq!( + Uuid::parse_str("231231212212423424324323477343246663") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidLength { + expected: EXPECTED_UUID_LENGTHS, + found: 36, + }) + ); + + // Valid + assert!(Uuid::parse_str("00000000000000000000000000000000").is_ok()); + assert!(Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8").is_ok()); + assert!(Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4").is_ok()); + assert!(Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c8").is_ok()); + assert!(Uuid::parse_str("01020304-1112-2122-3132-414243444546").is_ok()); + assert!(Uuid::parse_str( + "urn:uuid:67e55044-10b1-426f-9247-bb680e5fe0c8" + ) + .is_ok()); + + // Nil + let nil = Uuid::nil(); + assert_eq!( + Uuid::parse_str("00000000000000000000000000000000").unwrap(), + nil + ); + assert_eq!( + Uuid::parse_str("00000000-0000-0000-0000-000000000000").unwrap(), + nil + ); + + // Round-trip + let uuid_orig = test_util::new(); + let orig_str = uuid_orig.to_string(); + let uuid_out = Uuid::parse_str(&orig_str).unwrap(); + assert_eq!(uuid_orig, uuid_out); + + // Test error reporting + assert_eq!( + Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidLength { + expected: EXPECTED_UUID_LENGTHS, + found: 31, + }) + ); + assert_eq!( + Uuid::parse_str("67e550X410b1426f9247bb680e5fe0cd") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidCharacter { + expected: EXPECTED_CHARS, + found: 'X', + index: 6, + urn: error::UrnPrefix::Optional, + }) + ); + assert_eq!( + Uuid::parse_str("67e550-4105b1426f9247bb680e5fe0c") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidGroupLength { + expected: error::ExpectedLength::Exact(8), + found: 6, + group: 0, + }) + ); + assert_eq!( + Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF1-02BF39FA1E4") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidGroupLength { + expected: error::ExpectedLength::Exact(4), + found: 5, + group: 3, + }) + ); + } +} diff --git a/vendor/uuid/src/prelude.rs b/vendor/uuid/src/prelude.rs new file mode 100644 index 000000000..63fbb4bfb --- /dev/null +++ b/vendor/uuid/src/prelude.rs @@ -0,0 +1,47 @@ +// 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. + +//! The [`uuid`] prelude. +//! +//! This module contains the most important items of the [`uuid`] crate. +//! +//! To use the prelude, include the following in your crate root: +//! +//! ```rust +//! extern crate uuid; +//! ``` +//! +//! # Prelude Contents +//! +//! Currently the prelude reexports the following: +//! +//! [`uuid`]`::{`[`Error`], [`Uuid`], [`Variant`], [`Version`], +//! builder::[`Builder`]`}`: The fundamental types used in [`uuid`] crate. +//! +//! [`uuid`]: ../index.html +//! [`Error`]: ../enum.Error.html +//! [`Uuid`]: ../struct.Uuid.html +//! [`Variant`]: ../enum.Variant.html +//! [`Version`]: ../enum.Version.html +//! [`Builder`]: ../builder/struct.Builder.html +//! +#![cfg_attr(feature = "v1", +doc = " +[`uuid::v1`]`::{`[`ClockSequence`],[`Context`]`}`: The types useful for +handling uuid version 1. Requires feature `v1`. + +[`uuid::v1`]: ../v1/index.html +[`Context`]: ../v1/struct.Context.html +[`ClockSequence`]: ../v1/trait.ClockSequence.html")] + +pub use super::{Builder, Bytes, Error, Uuid, Variant, Version}; +#[cfg(feature = "v1")] +pub use crate::v1::{ClockSequence, Context}; diff --git a/vendor/uuid/src/serde_support.rs b/vendor/uuid/src/serde_support.rs new file mode 100644 index 000000000..4ec2ffbc0 --- /dev/null +++ b/vendor/uuid/src/serde_support.rs @@ -0,0 +1,125 @@ +// 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. + +use crate::prelude::*; +use core::fmt; +use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; + +impl Serialize for Uuid { + fn serialize( + &self, + serializer: S, + ) -> Result { + if serializer.is_human_readable() { + serializer + .serialize_str(&self.to_hyphenated().encode_lower(&mut [0; 36])) + } else { + serializer.serialize_bytes(self.as_bytes()) + } + } +} + +impl<'de> Deserialize<'de> for Uuid { + fn deserialize>( + deserializer: D, + ) -> Result { + fn de_error(e: crate::Error) -> E { + E::custom(format_args!("UUID parsing failed: {}", e)) + } + + if deserializer.is_human_readable() { + struct UuidStringVisitor; + + impl<'vi> de::Visitor<'vi> for UuidStringVisitor { + type Value = Uuid; + + fn expecting( + &self, + formatter: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + write!(formatter, "a UUID string") + } + + fn visit_str( + self, + value: &str, + ) -> Result { + value.parse::().map_err(de_error) + } + + fn visit_bytes( + self, + value: &[u8], + ) -> Result { + Uuid::from_slice(value).map_err(de_error) + } + } + + deserializer.deserialize_str(UuidStringVisitor) + } else { + struct UuidBytesVisitor; + + impl<'vi> de::Visitor<'vi> for UuidBytesVisitor { + type Value = Uuid; + + fn expecting( + &self, + formatter: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + write!(formatter, "bytes") + } + + fn visit_bytes( + self, + value: &[u8], + ) -> Result { + Uuid::from_slice(value).map_err(de_error) + } + } + + deserializer.deserialize_bytes(UuidBytesVisitor) + } + } +} + +#[cfg(test)] +mod serde_tests { + use serde_test::{Compact, Configure, Readable, Token}; + + use crate::prelude::*; + + #[test] + fn test_serialize_readable() { + let uuid_str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4"; + let u = Uuid::parse_str(uuid_str).unwrap(); + serde_test::assert_tokens(&u.readable(), &[Token::Str(uuid_str)]); + } + + #[test] + fn test_serialize_compact() { + let uuid_bytes = b"F9168C5E-CEB2-4F"; + let u = Uuid::from_slice(uuid_bytes).unwrap(); + serde_test::assert_tokens(&u.compact(), &[Token::Bytes(uuid_bytes)]); + } + + #[test] + fn test_de_failure() { + serde_test::assert_de_tokens_error::>( + &[Token::Str("hello_world")], + "UUID parsing failed: invalid length: expected one of [36, 32], found 11", + ); + + serde_test::assert_de_tokens_error::>( + &[Token::Bytes(b"hello_world")], + "UUID parsing failed: invalid bytes length: expected 16, found 11", + ); + } +} diff --git a/vendor/uuid/src/slog_support.rs b/vendor/uuid/src/slog_support.rs new file mode 100644 index 000000000..472b39aba --- /dev/null +++ b/vendor/uuid/src/slog_support.rs @@ -0,0 +1,39 @@ +// 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. + +use crate::prelude::*; +use slog; + +impl slog::Value for Uuid { + fn serialize( + &self, + _: &slog::Record<'_>, + key: slog::Key, + serializer: &mut dyn slog::Serializer, + ) -> Result<(), slog::Error> { + serializer.emit_arguments(key, &format_args!("{}", self)) + } +} + +#[cfg(test)] +mod tests { + + #[test] + fn test_slog_kv() { + use crate::test_util; + use slog; + use slog::{crit, Drain}; + + let root = slog::Logger::root(slog::Discard.fuse(), slog::o!()); + let u1 = test_util::new(); + crit!(root, "test"; "u1" => u1); + } +} diff --git a/vendor/uuid/src/test_util.rs b/vendor/uuid/src/test_util.rs new file mode 100644 index 000000000..ebb45abfd --- /dev/null +++ b/vendor/uuid/src/test_util.rs @@ -0,0 +1,26 @@ +// 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. + +use crate::prelude::*; + +pub const fn new() -> Uuid { + Uuid::from_bytes([ + 0xF9, 0x16, 0x8C, 0x5E, 0xCE, 0xB2, 0x4F, 0xAA, 0xB6, 0xBF, 0x32, 0x9B, + 0xF3, 0x9F, 0xA1, 0xE4, + ]) +} + +pub const fn new2() -> Uuid { + Uuid::from_bytes([ + 0xF9, 0x16, 0x8C, 0x5E, 0xCE, 0xB2, 0x4F, 0xAB, 0xB6, 0xBF, 0x32, 0x9B, + 0xF3, 0x9F, 0xA1, 0xE4, + ]) +} diff --git a/vendor/uuid/src/v1.rs b/vendor/uuid/src/v1.rs new file mode 100644 index 000000000..de692b768 --- /dev/null +++ b/vendor/uuid/src/v1.rs @@ -0,0 +1,326 @@ +//! The implementation for Version 1 UUIDs. +//! +//! Note that you need feature `v1` in order to use these features. + +use crate::prelude::*; +use core::sync::atomic; + +/// The number of 100 ns ticks between the UUID epoch +/// `1582-10-15 00:00:00` and the Unix epoch `1970-01-01 00:00:00`. +const UUID_TICKS_BETWEEN_EPOCHS: u64 = 0x01B2_1DD2_1381_4000; + +/// A thread-safe, stateful context for the v1 generator to help ensure +/// process-wide uniqueness. +#[derive(Debug)] +pub struct Context { + count: atomic::AtomicUsize, +} + +/// Stores the number of nanoseconds from an epoch and a counter for ensuring +/// V1 ids generated on the same host are unique. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct Timestamp { + ticks: u64, + counter: u16, +} + +impl Timestamp { + /// Construct a `Timestamp` from its raw component values: an RFC4122 + /// timestamp and counter. + /// + /// RFC4122, which defines the V1 UUID, specifies a 60-byte timestamp format + /// as the number of 100-nanosecond intervals elapsed since 00:00:00.00, + /// 15 Oct 1582, "the date of the Gregorian reform of the Christian + /// calendar." + /// + /// The counter value is used to differentiate between ids generated by + /// the same host computer in rapid succession (i.e. with the same observed + /// time). See the [`ClockSequence`] trait for a generic interface to any + /// counter generators that might be used. + /// + /// Internally, the timestamp is stored as a `u64`. For this reason, dates + /// prior to October 1582 are not supported. + /// + /// [`ClockSequence`]: trait.ClockSequence.html + pub const fn from_rfc4122(ticks: u64, counter: u16) -> Self { + Timestamp { ticks, counter } + } + + /// Construct a `Timestamp` from a unix timestamp and sequence-generating + /// `context`. + /// + /// A unix timestamp represents the elapsed time since Jan 1 1970. Libc's + /// `clock_gettime` and other popular implementations traditionally + /// represent this duration as a `timespec`: a struct with `u64` and + /// `u32` fields representing the seconds, and "subsecond" or fractional + /// nanoseconds elapsed since the timestamp's second began, + /// respectively. + /// + /// This constructs a `Timestamp` from the seconds and fractional + /// nanoseconds of a unix timestamp, converting the duration since 1970 + /// into the number of 100-nanosecond intervals since 00:00:00.00, 15 + /// Oct 1582 specified by RFC4122 and used internally by `Timestamp`. + /// + /// The function is not guaranteed to produce monotonically increasing + /// values however. There is a slight possibility that two successive + /// equal time values could be supplied and the sequence counter wraps back + /// over to 0. + /// + /// If uniqueness and monotonicity is required, the user is responsible for + /// ensuring that the time value always increases between calls (including + /// between restarts of the process and device). + pub fn from_unix( + context: impl ClockSequence, + seconds: u64, + subsec_nanos: u32, + ) -> Self { + let counter = context.generate_sequence(seconds, subsec_nanos); + let ticks = UUID_TICKS_BETWEEN_EPOCHS + + seconds * 10_000_000 + + u64::from(subsec_nanos) / 100; + + Timestamp { ticks, counter } + } + + /// Returns the raw RFC4122 timestamp and counter values stored by the + /// `Timestamp`. + /// + /// The timestamp (the first, `u64` element in the tuple) represents the + /// number of 100-nanosecond intervals since 00:00:00.00, 15 Oct 1582. + /// The counter is used to differentiate between ids generated on the + /// same host computer with the same observed time. + pub const fn to_rfc4122(&self) -> (u64, u16) { + (self.ticks, self.counter) + } + + /// Returns the timestamp converted to the seconds and fractional + /// nanoseconds since Jan 1 1970. + /// + /// Internally, the time is stored in 100-nanosecond intervals, + /// thus the maximum precision represented by the fractional nanoseconds + /// value is less than its unit size (100 ns vs. 1 ns). + pub const fn to_unix(&self) -> (u64, u32) { + ( + (self.ticks - UUID_TICKS_BETWEEN_EPOCHS) / 10_000_000, + ((self.ticks - UUID_TICKS_BETWEEN_EPOCHS) % 10_000_000) as u32 + * 100, + ) + } + + /// Returns the timestamp converted into nanoseconds elapsed since Jan 1 + /// 1970. Internally, the time is stored in 100-nanosecond intervals, + /// thus the maximum precision represented is less than the units it is + /// measured in (100 ns vs. 1 ns). The value returned represents the + /// same duration as [`Timestamp::to_unix`]; this provides it in nanosecond + /// units for convenience. + pub const fn to_unix_nanos(&self) -> u64 { + (self.ticks - UUID_TICKS_BETWEEN_EPOCHS) * 100 + } +} + +/// A trait that abstracts over generation of UUID v1 "Clock Sequence" values. +pub trait ClockSequence { + /// Return a 16-bit number that will be used as the "clock sequence" in + /// the UUID. The number must be different if the time has changed since + /// the last time a clock sequence was requested. + fn generate_sequence(&self, seconds: u64, subsec_nanos: u32) -> u16; +} + +impl<'a, T: ClockSequence + ?Sized> ClockSequence for &'a T { + fn generate_sequence(&self, seconds: u64, subsec_nanos: u32) -> u16 { + (**self).generate_sequence(seconds, subsec_nanos) + } +} + +impl Uuid { + /// Create a new UUID (version 1) using a time value + sequence + + /// *NodeId*. + /// + /// When generating [`Timestamp`]s using a [`ClockSequence`], this function + /// is only guaranteed to produce unique values if the following conditions + /// hold: + /// + /// 1. The *NodeId* is unique for this process, + /// 2. The *Context* is shared across all threads which are generating v1 + /// UUIDs, + /// 3. The [`ClockSequence`] implementation reliably returns unique + /// clock sequences (this crate provides [`Context`] for this + /// purpose. However you can create your own [`ClockSequence`] + /// implementation, if [`Context`] does not meet your needs). + /// + /// The NodeID must be exactly 6 bytes long. + /// + /// Note that usage of this method requires the `v1` feature of this crate + /// to be enabled. + /// + /// # Examples + /// + /// A UUID can be created from a unix [`Timestamp`] with a + /// [`ClockSequence`]: + /// + /// ```rust + /// use uuid::v1::{Timestamp, Context}; + /// use uuid::Uuid; + /// + /// let context = Context::new(42); + /// let ts = Timestamp::from_unix(&context, 1497624119, 1234); + /// let uuid = Uuid::new_v1(ts, &[1, 2, 3, 4, 5, 6]).expect("failed to generate UUID"); + /// + /// assert_eq!( + /// uuid.to_hyphenated().to_string(), + /// "f3b4958c-52a1-11e7-802a-010203040506" + /// ); + /// ``` + /// + /// The timestamp can also be created manually as per RFC4122: + /// + /// ``` + /// use uuid::v1::{Timestamp, Context}; + /// use uuid::Uuid; + /// + /// let context = Context::new(42); + /// let ts = Timestamp::from_rfc4122(1497624119, 0); + /// let uuid = Uuid::new_v1(ts, &[1, 2, 3, 4, 5, 6]).expect("failed to generate UUID"); + /// + /// assert_eq!( + /// uuid.to_hyphenated().to_string(), + /// "5943ee37-0000-1000-8000-010203040506" + /// ); + /// ``` + /// + /// [`Timestamp`]: v1/struct.Timestamp.html + /// [`ClockSequence`]: v1/struct.ClockSequence.html + /// [`Context`]: v1/struct.Context.html + pub fn new_v1(ts: Timestamp, node_id: &[u8]) -> Result { + const NODE_ID_LEN: usize = 6; + + let len = node_id.len(); + if len != NODE_ID_LEN { + Err(crate::builder::Error::new(NODE_ID_LEN, len))?; + } + + let time_low = (ts.ticks & 0xFFFF_FFFF) as u32; + let time_mid = ((ts.ticks >> 32) & 0xFFFF) as u16; + let time_high_and_version = + (((ts.ticks >> 48) & 0x0FFF) as u16) | (1 << 12); + + let mut d4 = [0; 8]; + + { + d4[0] = (((ts.counter & 0x3F00) >> 8) as u8) | 0x80; + d4[1] = (ts.counter & 0xFF) as u8; + } + + d4[2..].copy_from_slice(node_id); + + Uuid::from_fields(time_low, time_mid, time_high_and_version, &d4) + } + + /// Returns an optional [`Timestamp`] storing the timestamp and + /// counter portion parsed from a V1 UUID. + /// + /// Returns `None` if the supplied UUID is not V1. + /// + /// The V1 timestamp format defined in RFC4122 specifies a 60-bit + /// integer representing the number of 100-nanosecond intervals + /// since 00:00:00.00, 15 Oct 1582. + /// + /// [`Timestamp`] offers several options for converting the raw RFC4122 + /// value into more commonly-used formats, such as a unix timestamp. + /// + /// [`Timestamp`]: v1/struct.Timestamp.html + pub fn to_timestamp(&self) -> Option { + if self + .get_version() + .map(|v| v != Version::Mac) + .unwrap_or(true) + { + return None; + } + + let ticks: u64 = u64::from(self.as_bytes()[6] & 0x0F) << 56 + | u64::from(self.as_bytes()[7]) << 48 + | u64::from(self.as_bytes()[4]) << 40 + | u64::from(self.as_bytes()[5]) << 32 + | u64::from(self.as_bytes()[0]) << 24 + | u64::from(self.as_bytes()[1]) << 16 + | u64::from(self.as_bytes()[2]) << 8 + | u64::from(self.as_bytes()[3]); + + let counter: u16 = u16::from(self.as_bytes()[8] & 0x3F) << 8 + | u16::from(self.as_bytes()[9]); + + Some(Timestamp::from_rfc4122(ticks, counter)) + } +} + +impl Context { + /// Creates a thread-safe, internally mutable context to help ensure + /// uniqueness. + /// + /// This is a context which can be shared across threads. It maintains an + /// internal counter that is incremented at every request, the value ends + /// up in the clock_seq portion of the UUID (the fourth group). This + /// will improve the probability that the UUID is unique across the + /// process. + pub const fn new(count: u16) -> Self { + Self { + count: atomic::AtomicUsize::new(count as usize), + } + } +} + +impl ClockSequence for Context { + fn generate_sequence(&self, _: u64, _: u32) -> u16 { + (self.count.fetch_add(1, atomic::Ordering::SeqCst) & 0xffff) as u16 + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use crate::std::string::ToString; + + #[test] + fn test_new_v1() { + let time: u64 = 1_496_854_535; + let time_fraction: u32 = 812_946_000; + let node = [1, 2, 3, 4, 5, 6]; + let context = Context::new(0); + + { + let uuid = Uuid::new_v1( + Timestamp::from_unix(&context, time, time_fraction), + &node, + ) + .unwrap(); + + assert_eq!(uuid.get_version(), Some(Version::Mac)); + assert_eq!(uuid.get_variant(), Some(Variant::RFC4122)); + assert_eq!( + uuid.to_hyphenated().to_string(), + "20616934-4ba2-11e7-8000-010203040506" + ); + + let ts = uuid.to_timestamp().unwrap().to_rfc4122(); + + assert_eq!(ts.0 - 0x01B2_1DD2_1381_4000, 14_968_545_358_129_460); + assert_eq!(ts.1, 0); + }; + + { + let uuid2 = Uuid::new_v1( + Timestamp::from_unix(&context, time, time_fraction), + &node, + ) + .unwrap(); + + assert_eq!( + uuid2.to_hyphenated().to_string(), + "20616934-4ba2-11e7-8001-010203040506" + ); + assert_eq!(uuid2.to_timestamp().unwrap().to_rfc4122().1, 1) + }; + } +} diff --git a/vendor/uuid/src/v3.rs b/vendor/uuid/src/v3.rs new file mode 100644 index 000000000..5be542bb7 --- /dev/null +++ b/vendor/uuid/src/v3.rs @@ -0,0 +1,146 @@ +use crate::prelude::*; +use md5; + +impl Uuid { + /// Creates a UUID using a name from a namespace, based on the MD5 + /// hash. + /// + /// A number of namespaces are available as constants in this crate: + /// + /// * [`NAMESPACE_DNS`] + /// * [`NAMESPACE_OID`] + /// * [`NAMESPACE_URL`] + /// * [`NAMESPACE_X500`] + /// + /// Note that usage of this method requires the `v3` feature of this crate + /// to be enabled. + /// + /// [`NAMESPACE_DNS`]: #associatedconstant.NAMESPACE_DNS + /// [`NAMESPACE_OID`]: #associatedconstant.NAMESPACE_OID + /// [`NAMESPACE_URL`]: #associatedconstant.NAMESPACE_URL + /// [`NAMESPACE_X500`]: #associatedconstant.NAMESPACE_X500 + pub fn new_v3(namespace: &Uuid, name: &[u8]) -> Uuid { + let mut context = md5::Context::new(); + + context.consume(namespace.as_bytes()); + context.consume(name); + + let computed = context.compute(); + let bytes = computed.into(); + + let mut builder = crate::Builder::from_bytes(bytes); + + builder + .set_variant(Variant::RFC4122) + .set_version(Version::Md5); + + builder.build() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use crate::std::string::ToString; + + static FIXTURE: &'static [(&'static Uuid, &'static str, &'static str)] = &[ + ( + &Uuid::NAMESPACE_DNS, + "example.org", + "04738bdf-b25a-3829-a801-b21a1d25095b", + ), + ( + &Uuid::NAMESPACE_DNS, + "rust-lang.org", + "c6db027c-615c-3b4d-959e-1a917747ca5a", + ), + ( + &Uuid::NAMESPACE_DNS, + "42", + "5aab6e0c-b7d3-379c-92e3-2bfbb5572511", + ), + ( + &Uuid::NAMESPACE_DNS, + "lorem ipsum", + "4f8772e9-b59c-3cc9-91a9-5c823df27281", + ), + ( + &Uuid::NAMESPACE_URL, + "example.org", + "39682ca1-9168-3da2-a1bb-f4dbcde99bf9", + ), + ( + &Uuid::NAMESPACE_URL, + "rust-lang.org", + "7ed45aaf-e75b-3130-8e33-ee4d9253b19f", + ), + ( + &Uuid::NAMESPACE_URL, + "42", + "08998a0c-fcf4-34a9-b444-f2bfc15731dc", + ), + ( + &Uuid::NAMESPACE_URL, + "lorem ipsum", + "e55ad2e6-fb89-34e8-b012-c5dde3cd67f0", + ), + ( + &Uuid::NAMESPACE_OID, + "example.org", + "f14eec63-2812-3110-ad06-1625e5a4a5b2", + ), + ( + &Uuid::NAMESPACE_OID, + "rust-lang.org", + "6506a0ec-4d79-3e18-8c2b-f2b6b34f2b6d", + ), + ( + &Uuid::NAMESPACE_OID, + "42", + "ce6925a5-2cd7-327b-ab1c-4b375ac044e4", + ), + ( + &Uuid::NAMESPACE_OID, + "lorem ipsum", + "5dd8654f-76ba-3d47-bc2e-4d6d3a78cb09", + ), + ( + &Uuid::NAMESPACE_X500, + "example.org", + "64606f3f-bd63-363e-b946-fca13611b6f7", + ), + ( + &Uuid::NAMESPACE_X500, + "rust-lang.org", + "bcee7a9c-52f1-30c6-a3cc-8c72ba634990", + ), + ( + &Uuid::NAMESPACE_X500, + "42", + "c1073fa2-d4a6-3104-b21d-7a6bdcf39a23", + ), + ( + &Uuid::NAMESPACE_X500, + "lorem ipsum", + "02f09a3f-1624-3b1d-8409-44eff7708208", + ), + ]; + + #[test] + fn test_new() { + for &(ref ns, ref name, _) in FIXTURE { + let uuid = Uuid::new_v3(*ns, name.as_bytes()); + assert_eq!(uuid.get_version().unwrap(), Version::Md5); + assert_eq!(uuid.get_variant().unwrap(), Variant::RFC4122); + } + } + + #[test] + fn test_to_hyphenated_string() { + for &(ref ns, ref name, ref expected) in FIXTURE { + let uuid = Uuid::new_v3(*ns, name.as_bytes()); + assert_eq!(uuid.to_hyphenated().to_string(), *expected); + } + } +} diff --git a/vendor/uuid/src/v4.rs b/vendor/uuid/src/v4.rs new file mode 100644 index 000000000..0928dc75b --- /dev/null +++ b/vendor/uuid/src/v4.rs @@ -0,0 +1,60 @@ +use crate::prelude::*; + +impl Uuid { + /// Creates a random UUID. + /// + /// This uses the [`getrandom`] crate to utilise the operating system's RNG + /// as the source of random numbers. If you'd like to use a custom + /// generator, don't use this method: generate random bytes using your + /// custom generator and pass them to the + /// [`uuid::Builder::from_bytes`][from_bytes] function instead. + /// + /// Note that usage of this method requires the `v4` feature of this crate + /// to be enabled. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use uuid::Uuid; + /// + /// let uuid = Uuid::new_v4(); + /// ``` + /// + /// [`getrandom`]: https://crates.io/crates/getrandom + /// [from_bytes]: struct.Builder.html#method.from_bytes + pub fn new_v4() -> Uuid { + let mut bytes = [0u8; 16]; + getrandom::getrandom(&mut bytes).unwrap_or_else(|err| { + // NB: getrandom::Error has no source; this is adequate display + panic!("could not retreive random bytes for uuid: {}", err) + }); + + crate::Builder::from_bytes(bytes) + .set_variant(Variant::RFC4122) + .set_version(Version::Random) + .build() + } +} + +#[cfg(test)] +mod tests { + use crate::prelude::*; + + #[test] + fn test_new() { + let uuid = Uuid::new_v4(); + + assert_eq!(uuid.get_version(), Some(Version::Random)); + assert_eq!(uuid.get_variant(), Some(Variant::RFC4122)); + } + + #[test] + fn test_get_version() { + let uuid = Uuid::new_v4(); + + assert_eq!(uuid.get_version(), Some(Version::Random)); + assert_eq!(uuid.get_version_num(), 4) + } +} diff --git a/vendor/uuid/src/v5.rs b/vendor/uuid/src/v5.rs new file mode 100644 index 000000000..e42d70d9c --- /dev/null +++ b/vendor/uuid/src/v5.rs @@ -0,0 +1,158 @@ +use crate::prelude::*; +use sha1; + +impl Uuid { + /// Creates a UUID using a name from a namespace, based on the SHA-1 hash. + /// + /// A number of namespaces are available as constants in this crate: + /// + /// * [`NAMESPACE_DNS`] + /// * [`NAMESPACE_OID`] + /// * [`NAMESPACE_URL`] + /// * [`NAMESPACE_X500`] + /// + /// Note that usage of this method requires the `v5` feature of this crate + /// to be enabled. + /// + /// [`NAMESPACE_DNS`]: struct.Uuid.html#associatedconst.NAMESPACE_DNS + /// [`NAMESPACE_OID`]: struct.Uuid.html#associatedconst.NAMESPACE_OID + /// [`NAMESPACE_URL`]: struct.Uuid.html#associatedconst.NAMESPACE_URL + /// [`NAMESPACE_X500`]: struct.Uuid.html#associatedconst.NAMESPACE_X500 + pub fn new_v5(namespace: &Uuid, name: &[u8]) -> Uuid { + let mut hash = sha1::Sha1::new(); + + hash.update(namespace.as_bytes()); + hash.update(name); + + let buffer = hash.digest().bytes(); + + let mut bytes = crate::Bytes::default(); + bytes.copy_from_slice(&buffer[..16]); + + let mut builder = crate::Builder::from_bytes(bytes); + builder + .set_variant(Variant::RFC4122) + .set_version(Version::Sha1); + + builder.build() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use crate::std::string::ToString; + + static FIXTURE: &'static [(&'static Uuid, &'static str, &'static str)] = &[ + ( + &Uuid::NAMESPACE_DNS, + "example.org", + "aad03681-8b63-5304-89e0-8ca8f49461b5", + ), + ( + &Uuid::NAMESPACE_DNS, + "rust-lang.org", + "c66bbb60-d62e-5f17-a399-3a0bd237c503", + ), + ( + &Uuid::NAMESPACE_DNS, + "42", + "7c411b5e-9d3f-50b5-9c28-62096e41c4ed", + ), + ( + &Uuid::NAMESPACE_DNS, + "lorem ipsum", + "97886a05-8a68-5743-ad55-56ab2d61cf7b", + ), + ( + &Uuid::NAMESPACE_URL, + "example.org", + "54a35416-963c-5dd6-a1e2-5ab7bb5bafc7", + ), + ( + &Uuid::NAMESPACE_URL, + "rust-lang.org", + "c48d927f-4122-5413-968c-598b1780e749", + ), + ( + &Uuid::NAMESPACE_URL, + "42", + "5c2b23de-4bad-58ee-a4b3-f22f3b9cfd7d", + ), + ( + &Uuid::NAMESPACE_URL, + "lorem ipsum", + "15c67689-4b85-5253-86b4-49fbb138569f", + ), + ( + &Uuid::NAMESPACE_OID, + "example.org", + "34784df9-b065-5094-92c7-00bb3da97a30", + ), + ( + &Uuid::NAMESPACE_OID, + "rust-lang.org", + "8ef61ecb-977a-5844-ab0f-c25ef9b8d5d6", + ), + ( + &Uuid::NAMESPACE_OID, + "42", + "ba293c61-ad33-57b9-9671-f3319f57d789", + ), + ( + &Uuid::NAMESPACE_OID, + "lorem ipsum", + "6485290d-f79e-5380-9e64-cb4312c7b4a6", + ), + ( + &Uuid::NAMESPACE_X500, + "example.org", + "e3635e86-f82b-5bbc-a54a-da97923e5c76", + ), + ( + &Uuid::NAMESPACE_X500, + "rust-lang.org", + "26c9c3e9-49b7-56da-8b9f-a0fb916a71a3", + ), + ( + &Uuid::NAMESPACE_X500, + "42", + "e4b88014-47c6-5fe0-a195-13710e5f6e27", + ), + ( + &Uuid::NAMESPACE_X500, + "lorem ipsum", + "b11f79a5-1e6d-57ce-a4b5-ba8531ea03d0", + ), + ]; + + #[test] + fn test_get_version() { + let uuid = + Uuid::new_v5(&Uuid::NAMESPACE_DNS, "rust-lang.org".as_bytes()); + + assert_eq!(uuid.get_version(), Some(Version::Sha1)); + assert_eq!(uuid.get_version_num(), 5); + } + + #[test] + fn test_hyphenated() { + for &(ref ns, ref name, ref expected) in FIXTURE { + let uuid = Uuid::new_v5(*ns, name.as_bytes()); + + assert_eq!(uuid.to_hyphenated().to_string(), *expected) + } + } + + #[test] + fn test_new() { + for &(ref ns, ref name, ref u) in FIXTURE { + let uuid = Uuid::new_v5(*ns, name.as_bytes()); + + assert_eq!(uuid.get_variant(), Some(Variant::RFC4122)); + assert_eq!(uuid.get_version(), Some(Version::Sha1)); + assert_eq!(Ok(uuid), u.parse()); + } + } +} diff --git a/vendor/uuid/src/winapi_support.rs b/vendor/uuid/src/winapi_support.rs new file mode 100644 index 000000000..29bed064f --- /dev/null +++ b/vendor/uuid/src/winapi_support.rs @@ -0,0 +1,79 @@ +use crate::prelude::*; +use winapi::shared::guiddef; + +#[cfg(feature = "guid")] +impl Uuid { + /// Attempts to create a [`Uuid`] from a little endian winapi `GUID` + /// + /// [`Uuid`]: ../struct.Uuid.html + pub fn from_guid(guid: guiddef::GUID) -> Result { + Uuid::from_fields_le( + guid.Data1 as u32, + guid.Data2 as u16, + guid.Data3 as u16, + &(guid.Data4 as [u8; 8]), + ) + } + + /// Converts a [`Uuid`] into a little endian winapi `GUID` + /// + /// [`Uuid`]: ../struct.Uuid.html + pub fn to_guid(&self) -> guiddef::GUID { + let (data1, data2, data3, data4) = self.to_fields_le(); + + guiddef::GUID { + Data1: data1, + Data2: data2, + Data3: data3, + Data4: *data4, + } + } +} + +#[cfg(feature = "guid")] +#[cfg(test)] +mod tests { + use super::*; + + use crate::std::string::ToString; + use winapi::shared::guiddef; + + #[test] + fn test_from_guid() { + let guid = guiddef::GUID { + Data1: 0x4a35229d, + Data2: 0x5527, + Data3: 0x4f30, + Data4: [0x86, 0x47, 0x9d, 0xc5, 0x4e, 0x1e, 0xe1, 0xe8], + }; + + let uuid = Uuid::from_guid(guid).unwrap(); + assert_eq!( + "9d22354a-2755-304f-8647-9dc54e1ee1e8", + uuid.to_hyphenated().to_string() + ); + } + + #[test] + fn test_guid_roundtrip() { + let guid_in = guiddef::GUID { + Data1: 0x4a35229d, + Data2: 0x5527, + Data3: 0x4f30, + Data4: [0x86, 0x47, 0x9d, 0xc5, 0x4e, 0x1e, 0xe1, 0xe8], + }; + + let uuid = Uuid::from_guid(guid_in).unwrap(); + let guid_out = uuid.to_guid(); + + assert_eq!( + (guid_in.Data1, guid_in.Data2, guid_in.Data3, guid_in.Data4), + ( + guid_out.Data1, + guid_out.Data2, + guid_out.Data3, + guid_out.Data4 + ) + ); + } +} -- cgit v1.2.3