diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:18:32 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:18:32 +0000 |
commit | 4547b622d8d29df964fa2914213088b148c498fc (patch) | |
tree | 9fc6b25f3c3add6b745be9a2400a6e96140046e9 /vendor/uuid/src | |
parent | Releasing progress-linux version 1.66.0+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-4547b622d8d29df964fa2914213088b148c498fc.tar.xz rustc-4547b622d8d29df964fa2914213088b148c498fc.zip |
Merging upstream version 1.67.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/uuid/src')
-rw-r--r-- | vendor/uuid/src/adapter/compact.rs | 81 | ||||
-rw-r--r-- | vendor/uuid/src/adapter/mod.rs | 1027 | ||||
-rw-r--r-- | vendor/uuid/src/builder/error.rs | 52 | ||||
-rw-r--r-- | vendor/uuid/src/builder/mod.rs | 473 | ||||
-rw-r--r-- | vendor/uuid/src/error.rs | 79 | ||||
-rw-r--r-- | vendor/uuid/src/lib.rs | 1070 | ||||
-rw-r--r-- | vendor/uuid/src/parser/error.rs | 149 | ||||
-rw-r--r-- | vendor/uuid/src/parser/mod.rs | 447 | ||||
-rw-r--r-- | vendor/uuid/src/prelude.rs | 47 | ||||
-rw-r--r-- | vendor/uuid/src/serde_support.rs | 125 | ||||
-rw-r--r-- | vendor/uuid/src/slog_support.rs | 39 | ||||
-rw-r--r-- | vendor/uuid/src/test_util.rs | 26 | ||||
-rw-r--r-- | vendor/uuid/src/v1.rs | 326 | ||||
-rw-r--r-- | vendor/uuid/src/v3.rs | 146 | ||||
-rw-r--r-- | vendor/uuid/src/v4.rs | 60 | ||||
-rw-r--r-- | vendor/uuid/src/v5.rs | 158 | ||||
-rw-r--r-- | vendor/uuid/src/winapi_support.rs | 79 |
17 files changed, 4384 insertions, 0 deletions
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<S>(u: &crate::Uuid, serializer: S) -> Result<S::Ok, S::Error>
+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<crate::Uuid, D::Error>
+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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<Uuid> 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<Uuid, crate::Error> {
+ 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<Uuid, crate::Error> {
+ 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<Uuid, crate::Error> {
+ 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<Self, crate::Error> {
+ 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<Self, crate::Error> {
+ 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<builder::Error> for Error {
+ fn from(err: builder::Error) -> Self {
+ Error(Inner::Build(err))
+ }
+}
+
+impl From<parser::Error> 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<dyn std::error::Error>> {
+//! #[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<Variant> {
+ 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<Version> {
+ 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<Self, Self::Err> {
+ 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::<String>();
+
+ 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<Uuid, crate::Error> {
+ // 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<S: Serializer>(
+ &self,
+ serializer: S,
+ ) -> Result<S::Ok, S::Error> {
+ 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<D: Deserializer<'de>>(
+ deserializer: D,
+ ) -> Result<Self, D::Error> {
+ fn de_error<E: 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<E: de::Error>(
+ self,
+ value: &str,
+ ) -> Result<Uuid, E> {
+ value.parse::<Uuid>().map_err(de_error)
+ }
+
+ fn visit_bytes<E: de::Error>(
+ self,
+ value: &[u8],
+ ) -> Result<Uuid, E> {
+ 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<E: de::Error>(
+ self,
+ value: &[u8],
+ ) -> Result<Uuid, E> {
+ 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::<Readable<Uuid>>(
+ &[Token::Str("hello_world")],
+ "UUID parsing failed: invalid length: expected one of [36, 32], found 11",
+ );
+
+ serde_test::assert_de_tokens_error::<Compact<Uuid>>(
+ &[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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<Self, crate::Error> {
+ 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<Timestamp> {
+ 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, crate::Error> {
+ 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
+ )
+ );
+ }
+}
|