Vendor dependencies for 0.3.0 release

This commit is contained in:
2025-09-27 10:29:08 -05:00
parent 0c8d39d483
commit 82ab7f317b
26803 changed files with 16134934 additions and 0 deletions

878
vendor/uuid/src/builder.rs vendored Normal file
View File

@@ -0,0 +1,878 @@
// 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
use crate::{error::*, timestamp, Bytes, Uuid, Variant, Version};
/// A builder for creating a UUID.
///
/// This type is useful if you need to mutate individual fields of a [`Uuid`]
/// while constructing it. Since the [`Uuid`] type is `Copy`, it doesn't offer
/// any methods to mutate in place. They live on the `Builder` instead.
///
/// The `Builder` type also always exposes APIs to construct [`Uuid`]s for any
/// version without needing crate features or additional dependencies. It's a
/// lower-level API than the methods on [`Uuid`].
///
/// # Examples
///
/// Creating a version 4 UUID from externally generated random bytes:
///
/// ```
/// # use uuid::{Builder, Version, Variant};
/// # 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_random_bytes(random_bytes).into_uuid();
///
/// assert_eq!(Some(Version::Random), uuid.get_version());
/// assert_eq!(Variant::RFC4122, uuid.get_variant());
/// ```
#[allow(missing_copy_implementations)]
#[derive(Debug)]
pub struct Builder(Uuid);
impl Uuid {
/// The 'nil UUID' (all zeros).
///
/// The nil UUID is a special form of UUID that is specified to have all
/// 128 bits set to zero.
///
/// # References
///
/// * [Nil UUID in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-5.9)
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Uuid;
/// let uuid = Uuid::nil();
///
/// assert_eq!(
/// "00000000-0000-0000-0000-000000000000",
/// uuid.hyphenated().to_string(),
/// );
/// ```
pub const fn nil() -> Self {
Uuid::from_bytes([0; 16])
}
/// The 'max UUID' (all ones).
///
/// The max UUID is a special form of UUID that is specified to have all
/// 128 bits set to one.
///
/// # References
///
/// * [Max UUID in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-5.10)
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Uuid;
/// let uuid = Uuid::max();
///
/// assert_eq!(
/// "ffffffff-ffff-ffff-ffff-ffffffffffff",
/// uuid.hyphenated().to_string(),
/// );
/// ```
pub const fn max() -> Self {
Uuid::from_bytes([0xFF; 16])
}
/// Creates a UUID from four field values.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Uuid;
/// let d1 = 0xa1a2a3a4;
/// let d2 = 0xb1b2;
/// let d3 = 0xc1c2;
/// let d4 = [0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8];
///
/// let uuid = Uuid::from_fields(d1, d2, d3, &d4);
///
/// assert_eq!(
/// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8",
/// uuid.hyphenated().to_string(),
/// );
/// ```
pub const fn from_fields(d1: u32, d2: u16, d3: u16, d4: &[u8; 8]) -> Uuid {
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 flipped to convert
/// into big-endian order. This is based on the endianness of the UUID,
/// rather than the target environment so bytes will be flipped on both
/// big and little endian machines.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Uuid;
/// let d1 = 0xa1a2a3a4;
/// let d2 = 0xb1b2;
/// let d3 = 0xc1c2;
/// let d4 = [0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8];
///
/// let uuid = Uuid::from_fields_le(d1, d2, d3, &d4);
///
/// assert_eq!(
/// "a4a3a2a1-b2b1-c2c1-d1d2-d3d4d5d6d7d8",
/// uuid.hyphenated().to_string(),
/// );
/// ```
pub const fn from_fields_le(d1: u32, d2: u16, d3: u16, d4: &[u8; 8]) -> Uuid {
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.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Uuid;
/// let v = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8u128;
///
/// let uuid = Uuid::from_u128(v);
///
/// assert_eq!(
/// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8",
/// uuid.hyphenated().to_string(),
/// );
/// ```
pub const fn from_u128(v: u128) -> Self {
Uuid::from_bytes(v.to_be_bytes())
}
/// Creates a UUID from a 128bit value in little-endian order.
///
/// The entire value will be flipped to convert into big-endian order.
/// This is based on the endianness of the UUID, rather than the target
/// environment so bytes will be flipped on both big and little endian
/// machines.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Uuid;
/// let v = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8u128;
///
/// let uuid = Uuid::from_u128_le(v);
///
/// assert_eq!(
/// "d8d7d6d5-d4d3-d2d1-c2c1-b2b1a4a3a2a1",
/// uuid.hyphenated().to_string(),
/// );
/// ```
pub const fn from_u128_le(v: u128) -> Self {
Uuid::from_bytes(v.to_le_bytes())
}
/// Creates a UUID from two 64bit values.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Uuid;
/// let hi = 0xa1a2a3a4b1b2c1c2u64;
/// let lo = 0xd1d2d3d4d5d6d7d8u64;
///
/// let uuid = Uuid::from_u64_pair(hi, lo);
///
/// assert_eq!(
/// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8",
/// uuid.hyphenated().to_string(),
/// );
/// ```
pub const fn from_u64_pair(high_bits: u64, low_bits: u64) -> Self {
Uuid::from_u128(((high_bits as u128) << 64) | low_bits as u128)
}
/// Creates a UUID using the supplied bytes.
///
/// # Errors
///
/// This function will return an error if `b` has any length other than 16.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # fn main() -> Result<(), uuid::Error> {
/// # use uuid::Uuid;
/// let bytes = [
/// 0xa1, 0xa2, 0xa3, 0xa4,
/// 0xb1, 0xb2,
/// 0xc1, 0xc2,
/// 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
/// ];
///
/// let uuid = Uuid::from_slice(&bytes)?;
///
/// assert_eq!(
/// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8",
/// uuid.hyphenated().to_string(),
/// );
/// # Ok(())
/// # }
/// ```
pub fn from_slice(b: &[u8]) -> Result<Uuid, Error> {
if b.len() != 16 {
return Err(Error(ErrorKind::ParseByteLength { len: b.len() }));
}
let mut bytes: Bytes = [0; 16];
bytes.copy_from_slice(b);
Ok(Uuid::from_bytes(bytes))
}
/// Creates a UUID using the supplied bytes in little endian order.
///
/// The individual fields encoded in the buffer will be flipped.
///
/// # Errors
///
/// This function will return an error if `b` has any length other than 16.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # fn main() -> Result<(), uuid::Error> {
/// # use uuid::Uuid;
/// let bytes = [
/// 0xa1, 0xa2, 0xa3, 0xa4,
/// 0xb1, 0xb2,
/// 0xc1, 0xc2,
/// 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
/// ];
///
/// let uuid = Uuid::from_slice_le(&bytes)?;
///
/// assert_eq!(
/// uuid.hyphenated().to_string(),
/// "a4a3a2a1-b2b1-c2c1-d1d2-d3d4d5d6d7d8"
/// );
/// # Ok(())
/// # }
/// ```
pub fn from_slice_le(b: &[u8]) -> Result<Uuid, Error> {
if b.len() != 16 {
return Err(Error(ErrorKind::ParseByteLength { len: b.len() }));
}
let mut bytes: Bytes = [0; 16];
bytes.copy_from_slice(b);
Ok(Uuid::from_bytes_le(bytes))
}
/// Creates a UUID using the supplied bytes.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # fn main() -> Result<(), uuid::Error> {
/// # use uuid::Uuid;
/// let bytes = [
/// 0xa1, 0xa2, 0xa3, 0xa4,
/// 0xb1, 0xb2,
/// 0xc1, 0xc2,
/// 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
/// ];
///
/// let uuid = Uuid::from_bytes(bytes);
///
/// assert_eq!(
/// uuid.hyphenated().to_string(),
/// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8"
/// );
/// # Ok(())
/// # }
/// ```
#[inline]
pub const fn from_bytes(bytes: Bytes) -> Uuid {
Uuid(bytes)
}
/// Creates a UUID using the supplied bytes in little endian order.
///
/// The individual fields encoded in the buffer will be flipped.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # fn main() -> Result<(), uuid::Error> {
/// # use uuid::Uuid;
/// let bytes = [
/// 0xa1, 0xa2, 0xa3, 0xa4,
/// 0xb1, 0xb2,
/// 0xc1, 0xc2,
/// 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
/// ];
///
/// let uuid = Uuid::from_bytes_le(bytes);
///
/// assert_eq!(
/// "a4a3a2a1-b2b1-c2c1-d1d2-d3d4d5d6d7d8",
/// uuid.hyphenated().to_string(),
/// );
/// # Ok(())
/// # }
/// ```
pub const fn from_bytes_le(b: Bytes) -> Uuid {
Uuid([
b[3], b[2], b[1], b[0], b[5], b[4], b[7], b[6], b[8], b[9], b[10], b[11], b[12], b[13],
b[14], b[15],
])
}
/// Creates a reference to a UUID from a reference to the supplied bytes.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # fn main() -> Result<(), uuid::Error> {
/// # use uuid::Uuid;
/// let bytes = [
/// 0xa1, 0xa2, 0xa3, 0xa4,
/// 0xb1, 0xb2,
/// 0xc1, 0xc2,
/// 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
/// ];
///
/// let uuid = Uuid::from_bytes_ref(&bytes);
///
/// assert_eq!(
/// uuid.hyphenated().to_string(),
/// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8"
/// );
///
/// assert!(std::ptr::eq(
/// uuid as *const Uuid as *const u8,
/// &bytes as *const [u8; 16] as *const u8,
/// ));
/// # Ok(())
/// # }
/// ```
#[inline]
pub fn from_bytes_ref(bytes: &Bytes) -> &Uuid {
unsafe_transmute_ref!(bytes)
}
// NOTE: There is no `from_u128_ref` because in little-endian
// environments the value isn't properly encoded. Callers would
// need to use `.to_be()` themselves.
}
impl Builder {
/// Creates a `Builder` using the supplied bytes.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Builder;
/// let bytes = [
/// 0xa1, 0xa2, 0xa3, 0xa4,
/// 0xb1, 0xb2,
/// 0xc1, 0xc2,
/// 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
/// ];
///
/// let uuid = Builder::from_bytes(bytes).into_uuid();
///
/// assert_eq!(
/// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8",
/// uuid.hyphenated().to_string(),
/// );
/// ```
pub const fn from_bytes(b: Bytes) -> Self {
Builder(Uuid::from_bytes(b))
}
/// Creates a `Builder` using the supplied bytes in little endian order.
///
/// The individual fields encoded in the buffer will be flipped.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # fn main() -> Result<(), uuid::Error> {
/// # use uuid::{Builder, Uuid};
/// let bytes = [
/// 0xa1, 0xa2, 0xa3, 0xa4,
/// 0xb1, 0xb2,
/// 0xc1, 0xc2,
/// 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
/// ];
///
/// let uuid = Builder::from_bytes_le(bytes).into_uuid();
///
/// assert_eq!(
/// "a4a3a2a1-b2b1-c2c1-d1d2-d3d4d5d6d7d8",
/// uuid.hyphenated().to_string(),
/// );
/// # Ok(())
/// # }
/// ```
pub const fn from_bytes_le(b: Bytes) -> Self {
Builder(Uuid::from_bytes_le(b))
}
/// Creates a `Builder` for a version 1 UUID using the supplied timestamp, counter, and node ID.
pub const fn from_gregorian_timestamp(ticks: u64, counter: u16, node_id: &[u8; 6]) -> Self {
Builder(timestamp::encode_gregorian_timestamp(
ticks, counter, node_id,
))
}
/// Creates a `Builder` for a version 3 UUID using the supplied MD5 hashed bytes.
pub const fn from_md5_bytes(md5_bytes: Bytes) -> Self {
Builder(Uuid::from_bytes(md5_bytes))
.with_variant(Variant::RFC4122)
.with_version(Version::Md5)
}
/// Creates a `Builder` for a version 4 UUID using the supplied random bytes.
///
/// This method assumes the bytes are already sufficiently random, it will only
/// set the appropriate bits for the UUID version and variant.
///
/// # Examples
///
/// ```
/// # 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_random_bytes(random_bytes).into_uuid();
///
/// assert_eq!(Some(Version::Random), uuid.get_version());
/// assert_eq!(Variant::RFC4122, uuid.get_variant());
/// ```
pub const fn from_random_bytes(random_bytes: Bytes) -> Self {
Builder(Uuid::from_bytes(random_bytes))
.with_variant(Variant::RFC4122)
.with_version(Version::Random)
}
/// Creates a `Builder` for a version 5 UUID using the supplied SHA-1 hashed bytes.
///
/// This method assumes the bytes are already a SHA-1 hash, it will only set the appropriate
/// bits for the UUID version and variant.
pub const fn from_sha1_bytes(sha1_bytes: Bytes) -> Self {
Builder(Uuid::from_bytes(sha1_bytes))
.with_variant(Variant::RFC4122)
.with_version(Version::Sha1)
}
/// Creates a `Builder` for a version 6 UUID using the supplied timestamp, counter, and node ID.
///
/// This method will encode the ticks, counter, and node ID in a sortable UUID.
pub const fn from_sorted_gregorian_timestamp(
ticks: u64,
counter: u16,
node_id: &[u8; 6],
) -> Self {
Builder(timestamp::encode_sorted_gregorian_timestamp(
ticks, counter, node_id,
))
}
/// Creates a `Builder` for a version 7 UUID using the supplied Unix timestamp and counter bytes.
///
/// This method will set the variant field within the counter bytes without attempting to shift
/// the data around it. Callers using the counter as a monotonic value should be careful not to
/// store significant data in the 2 least significant bits of the 3rd byte.
///
/// # Examples
///
/// Creating a UUID using the current system timestamp:
///
/// ```
/// # use std::convert::TryInto;
/// use std::time::{Duration, SystemTime};
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// # use uuid::{Builder, Uuid, Variant, Version, Timestamp, NoContext};
/// # let rng = || [
/// # 70, 235, 208, 238, 14, 109, 67, 201, 185, 13
/// # ];
/// let ts = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?;
///
/// let random_bytes = rng();
///
/// let uuid = Builder::from_unix_timestamp_millis(ts.as_millis().try_into()?, &random_bytes).into_uuid();
///
/// assert_eq!(Some(Version::SortRand), uuid.get_version());
/// assert_eq!(Variant::RFC4122, uuid.get_variant());
/// # Ok(())
/// # }
/// ```
pub const fn from_unix_timestamp_millis(millis: u64, counter_random_bytes: &[u8; 10]) -> Self {
Builder(timestamp::encode_unix_timestamp_millis(
millis,
counter_random_bytes,
))
}
/// Creates a `Builder` for a version 8 UUID using the supplied user-defined bytes.
///
/// This method won't interpret the given bytes in any way, except to set the appropriate
/// bits for the UUID version and variant.
pub const fn from_custom_bytes(custom_bytes: Bytes) -> Self {
Builder::from_bytes(custom_bytes)
.with_variant(Variant::RFC4122)
.with_version(Version::Custom)
}
/// Creates a `Builder` using the supplied bytes.
///
/// # Errors
///
/// This function will return an error if `b` has any length other than 16.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Builder;
/// # fn main() -> Result<(), uuid::Error> {
/// let bytes = [
/// 0xa1, 0xa2, 0xa3, 0xa4,
/// 0xb1, 0xb2,
/// 0xc1, 0xc2,
/// 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
/// ];
///
/// let uuid = Builder::from_slice(&bytes)?.into_uuid();
///
/// assert_eq!(
/// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8",
/// uuid.hyphenated().to_string(),
/// );
/// # Ok(())
/// # }
/// ```
pub fn from_slice(b: &[u8]) -> Result<Self, Error> {
Ok(Builder(Uuid::from_slice(b)?))
}
/// Creates a `Builder` using the supplied bytes in little endian order.
///
/// The individual fields encoded in the buffer will be flipped.
///
/// # Errors
///
/// This function will return an error if `b` has any length other than 16.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Builder;
/// # fn main() -> Result<(), uuid::Error> {
/// let bytes = [
/// 0xa1, 0xa2, 0xa3, 0xa4,
/// 0xb1, 0xb2,
/// 0xc1, 0xc2,
/// 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
/// ];
///
/// let uuid = Builder::from_slice_le(&bytes)?.into_uuid();
///
/// assert_eq!(
/// "a4a3a2a1-b2b1-c2c1-d1d2-d3d4d5d6d7d8",
/// uuid.hyphenated().to_string(),
/// );
/// # Ok(())
/// # }
/// ```
pub fn from_slice_le(b: &[u8]) -> Result<Self, Error> {
Ok(Builder(Uuid::from_slice_le(b)?))
}
/// Creates a `Builder` from four field values.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Builder;
/// let d1 = 0xa1a2a3a4;
/// let d2 = 0xb1b2;
/// let d3 = 0xc1c2;
/// let d4 = [0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8];
///
/// let uuid = Builder::from_fields(d1, d2, d3, &d4).into_uuid();
///
/// assert_eq!(
/// uuid.hyphenated().to_string(),
/// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8"
/// );
/// ```
pub const fn from_fields(d1: u32, d2: u16, d3: u16, d4: &[u8; 8]) -> Self {
Builder(Uuid::from_fields(d1, d2, d3, d4))
}
/// Creates a `Builder` from four field values.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Builder;
/// let d1 = 0xa1a2a3a4;
/// let d2 = 0xb1b2;
/// let d3 = 0xc1c2;
/// let d4 = [0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8];
///
/// let uuid = Builder::from_fields_le(d1, d2, d3, &d4).into_uuid();
///
/// assert_eq!(
/// uuid.hyphenated().to_string(),
/// "a4a3a2a1-b2b1-c2c1-d1d2-d3d4d5d6d7d8"
/// );
/// ```
pub const fn from_fields_le(d1: u32, d2: u16, d3: u16, d4: &[u8; 8]) -> Self {
Builder(Uuid::from_fields_le(d1, d2, d3, d4))
}
/// Creates a `Builder` from a 128bit value.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Builder;
/// let v = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8u128;
///
/// let uuid = Builder::from_u128(v).into_uuid();
///
/// assert_eq!(
/// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8",
/// uuid.hyphenated().to_string(),
/// );
/// ```
pub const fn from_u128(v: u128) -> Self {
Builder(Uuid::from_u128(v))
}
/// Creates a UUID from a 128bit value in little-endian order.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Builder;
/// let v = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8u128;
///
/// let uuid = Builder::from_u128_le(v).into_uuid();
///
/// assert_eq!(
/// "d8d7d6d5-d4d3-d2d1-c2c1-b2b1a4a3a2a1",
/// uuid.hyphenated().to_string(),
/// );
/// ```
pub const fn from_u128_le(v: u128) -> Self {
Builder(Uuid::from_u128_le(v))
}
/// Creates a `Builder` with an initial [`Uuid::nil`].
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Builder;
/// let uuid = Builder::nil().into_uuid();
///
/// assert_eq!(
/// "00000000-0000-0000-0000-000000000000",
/// uuid.hyphenated().to_string(),
/// );
/// ```
pub const fn nil() -> Self {
Builder(Uuid::nil())
}
/// Specifies the variant of the UUID.
pub fn set_variant(&mut self, v: Variant) -> &mut Self {
*self = Builder(self.0).with_variant(v);
self
}
/// Specifies the variant of the UUID.
pub const fn with_variant(mut self, v: Variant) -> Self {
let byte = (self.0).0[8];
(self.0).0[8] = match v {
Variant::NCS => byte & 0x7f,
Variant::RFC4122 => (byte & 0x3f) | 0x80,
Variant::Microsoft => (byte & 0x1f) | 0xc0,
Variant::Future => byte | 0xe0,
};
self
}
/// Specifies the version number of the UUID.
pub fn set_version(&mut self, v: Version) -> &mut Self {
*self = Builder(self.0).with_version(v);
self
}
/// Specifies the version number of the UUID.
pub const fn with_version(mut self, v: Version) -> Self {
(self.0).0[6] = ((self.0).0[6] & 0x0f) | ((v as u8) << 4);
self
}
/// Get a reference to the underlying [`Uuid`].
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Builder;
/// let builder = Builder::nil();
///
/// let uuid1 = builder.as_uuid();
/// let uuid2 = builder.as_uuid();
///
/// assert_eq!(uuid1, uuid2);
/// ```
pub const fn as_uuid(&self) -> &Uuid {
&self.0
}
/// Convert the builder into a [`Uuid`].
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Builder;
/// let uuid = Builder::nil().into_uuid();
///
/// assert_eq!(
/// uuid.hyphenated().to_string(),
/// "00000000-0000-0000-0000-000000000000"
/// );
/// ```
pub const fn into_uuid(self) -> Uuid {
self.0
}
}
#[doc(hidden)]
impl Builder {
#[deprecated(
since = "1.10.0",
note = "use `Builder::from_gregorian_timestamp(ticks, counter, node_id)`"
)]
pub const fn from_rfc4122_timestamp(ticks: u64, counter: u16, node_id: &[u8; 6]) -> Self {
Builder::from_gregorian_timestamp(ticks, counter, node_id)
}
#[deprecated(
since = "1.10.0",
note = "use `Builder::from_sorted_gregorian_timestamp(ticks, counter, node_id)`"
)]
pub const fn from_sorted_rfc4122_timestamp(
ticks: u64,
counter: u16,
node_id: &[u8; 6],
) -> Self {
Builder::from_sorted_gregorian_timestamp(ticks, counter, node_id)
}
}

180
vendor/uuid/src/error.rs vendored Normal file
View File

@@ -0,0 +1,180 @@
use crate::std::fmt;
/// A general error that can occur when working with UUIDs.
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct Error(pub(crate) ErrorKind);
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub(crate) enum ErrorKind {
/// Invalid character in the [`Uuid`] string.
///
/// [`Uuid`]: ../struct.Uuid.html
ParseChar { character: char, index: usize },
/// A simple [`Uuid`] didn't contain 32 characters.
///
/// [`Uuid`]: ../struct.Uuid.html
ParseSimpleLength { len: usize },
/// A byte array didn't contain 16 bytes
ParseByteLength { len: usize },
/// A hyphenated [`Uuid`] didn't contain 5 groups
///
/// [`Uuid`]: ../struct.Uuid.html
ParseGroupCount { count: usize },
/// A hyphenated [`Uuid`] had a group that wasn't the right length
///
/// [`Uuid`]: ../struct.Uuid.html
ParseGroupLength {
group: usize,
len: usize,
index: usize,
},
/// The input was not a valid UTF8 string
ParseInvalidUTF8,
/// Some other parsing error occurred.
ParseOther,
/// The UUID is nil.
Nil,
/// A system time was invalid.
#[cfg(feature = "std")]
InvalidSystemTime(&'static str),
}
/// A string that is guaranteed to fail to parse to a [`Uuid`].
///
/// This type acts as a lightweight error indicator, suggesting
/// that the string cannot be parsed but offering no error
/// details. To get details, use `InvalidUuid::into_err`.
///
/// [`Uuid`]: ../struct.Uuid.html
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct InvalidUuid<'a>(pub(crate) &'a [u8]);
impl<'a> InvalidUuid<'a> {
/// Converts the lightweight error type into detailed diagnostics.
pub fn into_err(self) -> Error {
// Check whether or not the input was ever actually a valid UTF8 string
let input_str = match std::str::from_utf8(self.0) {
Ok(s) => s,
Err(_) => return Error(ErrorKind::ParseInvalidUTF8),
};
let (uuid_str, offset, simple) = match input_str.as_bytes() {
[b'{', s @ .., b'}'] => (s, 1, false),
[b'u', b'r', b'n', b':', b'u', b'u', b'i', b'd', b':', s @ ..] => {
(s, "urn:uuid:".len(), false)
}
s => (s, 0, true),
};
let mut hyphen_count = 0;
let mut group_bounds = [0; 4];
// SAFETY: the byte array came from a valid utf8 string,
// and is aligned along char boundaries.
let uuid_str = unsafe { std::str::from_utf8_unchecked(uuid_str) };
for (index, character) in uuid_str.char_indices() {
let byte = character as u8;
if character as u32 - byte as u32 > 0 {
// Multibyte char
return Error(ErrorKind::ParseChar {
character,
index: index + offset + 1,
});
} else if byte == b'-' {
// While we search, also count group breaks
if hyphen_count < 4 {
group_bounds[hyphen_count] = index;
}
hyphen_count += 1;
} else if !byte.is_ascii_hexdigit() {
// Non-hex char
return Error(ErrorKind::ParseChar {
character: byte as char,
index: index + offset + 1,
});
}
}
if hyphen_count == 0 && simple {
// This means that we tried and failed to parse a simple uuid.
// Since we verified that all the characters are valid, this means
// that it MUST have an invalid length.
Error(ErrorKind::ParseSimpleLength {
len: input_str.len(),
})
} else if hyphen_count != 4 {
// We tried to parse a hyphenated variant, but there weren't
// 5 groups (4 hyphen splits).
Error(ErrorKind::ParseGroupCount {
count: hyphen_count + 1,
})
} else {
// There are 5 groups, one of them has an incorrect length
const BLOCK_STARTS: [usize; 5] = [0, 9, 14, 19, 24];
for i in 0..4 {
if group_bounds[i] != BLOCK_STARTS[i + 1] - 1 {
return Error(ErrorKind::ParseGroupLength {
group: i,
len: group_bounds[i] - BLOCK_STARTS[i],
index: offset + BLOCK_STARTS[i] + 1,
});
}
}
// The last group must be too long
Error(ErrorKind::ParseGroupLength {
group: 4,
len: input_str.len() - BLOCK_STARTS[4],
index: offset + BLOCK_STARTS[4] + 1,
})
}
}
}
// NOTE: This impl is part of the public API. Breaking changes to it should be carefully considered
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.0 {
ErrorKind::ParseChar {
character, index, ..
} => {
write!(f, "invalid character: expected an optional prefix of `urn:uuid:` followed by [0-9a-fA-F-], found `{}` at {}", character, index)
}
ErrorKind::ParseSimpleLength { len } => {
write!(
f,
"invalid length: expected length 32 for simple format, found {}",
len
)
}
ErrorKind::ParseByteLength { len } => {
write!(f, "invalid length: expected 16 bytes, found {}", len)
}
ErrorKind::ParseGroupCount { count } => {
write!(f, "invalid group count: expected 5, found {}", count)
}
ErrorKind::ParseGroupLength { group, len, .. } => {
let expected = [8, 4, 4, 4, 12][group];
write!(
f,
"invalid group length in group {}: expected {}, found {}",
group, expected, len
)
}
ErrorKind::ParseInvalidUTF8 => write!(f, "non-UTF8 input"),
ErrorKind::Nil => write!(f, "the UUID is nil"),
ErrorKind::ParseOther => write!(f, "failed to parse a UUID"),
#[cfg(feature = "std")]
ErrorKind::InvalidSystemTime(ref e) => write!(f, "the system timestamp is invalid: {e}"),
}
}
}
#[cfg(feature = "std")]
mod std_support {
use super::*;
use crate::std::error;
impl error::Error for Error { }
}

8
vendor/uuid/src/external.rs vendored Normal file
View File

@@ -0,0 +1,8 @@
#[cfg(feature = "arbitrary")]
pub(crate) mod arbitrary_support;
#[cfg(feature = "borsh")]
pub(crate) mod borsh_support;
#[cfg(feature = "serde")]
pub(crate) mod serde_support;
#[cfg(feature = "slog")]
pub(crate) mod slog_support;

View File

@@ -0,0 +1,71 @@
use crate::{
non_nil::NonNilUuid,
std::convert::{TryFrom, TryInto},
Builder, Uuid,
};
use arbitrary::{Arbitrary, Unstructured};
impl Arbitrary<'_> for Uuid {
fn arbitrary(u: &mut Unstructured<'_>) -> arbitrary::Result<Self> {
let b = u
.bytes(16)?
.try_into()
.map_err(|_| arbitrary::Error::NotEnoughData)?;
Ok(Builder::from_random_bytes(b).into_uuid())
}
fn size_hint(_: usize) -> (usize, Option<usize>) {
(16, Some(16))
}
}
impl arbitrary::Arbitrary<'_> for NonNilUuid {
fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
let uuid = Uuid::arbitrary(u)?;
Self::try_from(uuid).map_err(|_| arbitrary::Error::IncorrectFormat)
}
fn size_hint(_: usize) -> (usize, Option<usize>) {
(16, Some(16))
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{Variant, Version};
#[test]
fn test_arbitrary() {
let mut bytes = Unstructured::new(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
let uuid = Uuid::arbitrary(&mut bytes).unwrap();
assert_eq!(Some(Version::Random), uuid.get_version());
assert_eq!(Variant::RFC4122, uuid.get_variant());
}
#[test]
fn test_arbitrary_empty() {
let mut bytes = Unstructured::new(&[]);
// Ensure we don't panic when building an arbitrary `Uuid`
let uuid = Uuid::arbitrary(&mut bytes);
assert!(uuid.is_err());
}
#[test]
fn test_arbitrary_non_nil() {
let mut bytes = Unstructured::new(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
let non_nil_uuid = NonNilUuid::arbitrary(&mut bytes).unwrap();
let uuid: Uuid = non_nil_uuid.into();
assert_eq!(Some(Version::Random), uuid.get_version());
assert_eq!(Variant::RFC4122, uuid.get_variant());
assert!(!uuid.is_nil());
}
}

View File

@@ -0,0 +1,23 @@
#[cfg(test)]
mod borsh_tests {
use crate::Uuid;
use std::string::ToString;
#[test]
fn test_serialize() {
let uuid_str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
let uuid = Uuid::parse_str(uuid_str).unwrap();
let uuid_bytes = uuid.as_bytes().to_vec();
let borsh_bytes = borsh::to_vec(&uuid).unwrap();
assert_eq!(uuid_bytes, borsh_bytes);
}
#[test]
fn test_deserialize() {
let uuid_str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
let uuid = Uuid::parse_str(uuid_str).unwrap();
let uuid_bytes = uuid.as_bytes().to_vec();
let deserialized = borsh::from_slice::<Uuid>(&uuid_bytes).unwrap().to_string();
assert_eq!(uuid_str, deserialized);
}
}

View File

@@ -0,0 +1,769 @@
// 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::{
convert::TryFrom,
error::*,
fmt::{Braced, Hyphenated, Simple, Urn},
non_nil::NonNilUuid,
std::fmt,
Uuid,
};
use serde::{
de::{self, Error as _},
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.hyphenated().encode_lower(&mut Uuid::encode_buffer()))
} else {
serializer.serialize_bytes(self.as_bytes())
}
}
}
impl Serialize for NonNilUuid {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
Uuid::from(*self).serialize(serializer)
}
}
impl Serialize for Hyphenated {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
}
}
impl Serialize for Simple {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
}
}
impl Serialize for Urn {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
}
}
impl Serialize for Braced {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
}
}
impl<'de> Deserialize<'de> for Uuid {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
fn de_error<E: de::Error>(e: Error) -> E {
E::custom(format_args!("UUID parsing failed: {}", e))
}
if deserializer.is_human_readable() {
struct UuidVisitor;
impl<'vi> de::Visitor<'vi> for UuidVisitor {
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)
}
fn visit_seq<A>(self, mut seq: A) -> Result<Uuid, A::Error>
where
A: de::SeqAccess<'vi>,
{
#[rustfmt::skip]
let bytes = [
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(0, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(1, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(2, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(3, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(4, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(5, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(6, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(7, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(8, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(9, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(10, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(11, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(12, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(13, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(14, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(15, &self)) },
];
Ok(Uuid::from_bytes(bytes))
}
}
deserializer.deserialize_str(UuidVisitor)
} 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)
}
}
}
impl<'de> Deserialize<'de> for NonNilUuid {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let uuid = Uuid::deserialize(deserializer)?;
NonNilUuid::try_from(uuid).map_err(|_| {
de::Error::invalid_value(de::Unexpected::Other("nil UUID"), &"a non-nil UUID")
})
}
}
enum ExpectedFormat {
Simple,
Braced,
Urn,
}
impl std::fmt::Display for ExpectedFormat {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let s = match self {
ExpectedFormat::Simple => "a simple Uuid string like 67e5504410b1426f9247bb680e5fe0c8",
ExpectedFormat::Braced => {
"a braced Uuid string like {67e55044-10b1-426f-9247-bb680e5fe0c8}"
}
ExpectedFormat::Urn => {
"a URN Uuid string like urn:uuid:67e55044-10b1-426f-9247-bb680e5fe0c8"
}
};
f.write_str(s)
}
}
impl de::Expected for ExpectedFormat {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
<ExpectedFormat as std::fmt::Display>::fmt(self, formatter)
}
}
pub mod compact {
//! Serialize a [`Uuid`] as a `[u8; 16]`.
//!
//! [`Uuid`]: ../../struct.Uuid.html
/// Serialize from a [`Uuid`] as 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)
}
/// Deserialize a `[u8; 16]` as 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_derive::*;
use serde_test::Configure;
#[test]
fn test_serialize_compact() {
#[derive(Serialize, Debug, Deserialize, PartialEq)]
struct UuidContainer {
#[serde(with = "crate::serde::compact")]
u: crate::Uuid,
}
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,
],
)
}
}
}
/// Serialize from a [`Uuid`] as a `uuid::fmt::Simple`
///
/// [`Uuid`]: ../../struct.Uuid.html
///
/// ## Example
///
/// ```rust
/// #[derive(serde_derive::Serialize, serde_derive::Deserialize)]
/// struct StructA {
/// // This will change both serailization and deserialization
/// #[serde(with = "uuid::serde::simple")]
/// id: uuid::Uuid,
/// }
///
/// #[derive(serde_derive::Serialize, serde_derive::Deserialize)]
/// struct StructB {
/// // This will be serialized as uuid::fmt::Simple and deserialize from all valid formats
/// #[serde(serialize_with = "uuid::serde::simple::serialize")]
/// id: uuid::Uuid,
/// }
/// ```
pub mod simple {
use serde::{de, Deserialize};
use crate::{parser::parse_simple, Uuid};
use super::ExpectedFormat;
/// Serialize from a [`Uuid`] as a `uuid::fmt::Simple`
///
/// [`Uuid`]: ../../struct.Uuid.html
///
/// # Example
///
/// ```rust
/// #[derive(serde_derive::Serialize)]
/// struct Struct {
/// // This will be serialize as uuid::fmt::Simple
/// #[serde(serialize_with = "uuid::serde::simple::serialize")]
/// id: uuid::Uuid,
/// }
///
/// ```
pub fn serialize<S>(u: &crate::Uuid, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serde::Serialize::serialize(u.as_simple(), serializer)
}
/// Deserialize a simple Uuid string as a [`Uuid`]
///
/// [`Uuid`]: ../../struct.Uuid.html
pub fn deserialize<'de, D>(deserializer: D) -> Result<Uuid, D::Error>
where
D: serde::Deserializer<'de>,
{
let s = <&str as Deserialize>::deserialize(deserializer)?;
let bytes = parse_simple(s.as_bytes()).map_err(|_| {
de::Error::invalid_value(de::Unexpected::Str(s), &ExpectedFormat::Simple)
})?;
Ok(Uuid::from_bytes(bytes))
}
#[cfg(test)]
mod tests {
use serde::de::{self, Error};
use serde_test::{Readable, Token};
use crate::{external::serde_support::ExpectedFormat, Uuid};
const HYPHENATED_UUID_STR: &'static str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
const SIMPLE_UUID_STR: &'static str = "f9168c5eceb24faab6bf329bf39fa1e4";
#[test]
fn test_serialize_as_simple() {
#[derive(serde_derive::Serialize)]
struct Struct(#[serde(with = "super")] crate::Uuid);
let u = Struct(Uuid::parse_str(HYPHENATED_UUID_STR).unwrap());
serde_test::assert_ser_tokens(
&u,
&[
Token::NewtypeStruct { name: "Struct" },
Token::Str(SIMPLE_UUID_STR),
],
);
}
#[test]
fn test_de_from_simple() {
#[derive(PartialEq, Debug, serde_derive::Deserialize)]
struct Struct(#[serde(with = "super")] crate::Uuid);
let s = Struct(HYPHENATED_UUID_STR.parse().unwrap());
serde_test::assert_de_tokens::<Struct>(
&s,
&[
Token::TupleStruct {
name: "Struct",
len: 1,
},
Token::BorrowedStr(SIMPLE_UUID_STR),
Token::TupleStructEnd,
],
);
}
#[test]
fn test_de_reject_hypenated() {
#[derive(PartialEq, Debug, serde_derive::Deserialize)]
struct Struct(#[serde(with = "super")] crate::Uuid);
serde_test::assert_de_tokens_error::<Readable<Struct>>(
&[
Token::TupleStruct {
name: "Struct",
len: 1,
},
Token::BorrowedStr(HYPHENATED_UUID_STR),
Token::TupleStructEnd,
],
&format!(
"{}",
de::value::Error::invalid_value(
de::Unexpected::Str(HYPHENATED_UUID_STR),
&ExpectedFormat::Simple,
)
),
);
}
}
}
/// Serialize from a [`Uuid`] as a `uuid::fmt::Braced`
///
/// [`Uuid`]: ../../struct.Uuid.html
///
/// ## Example
///
/// ```rust
/// #[derive(serde_derive::Serialize, serde_derive::Deserialize)]
/// struct StructA {
/// // This will change both serailization and deserialization
/// #[serde(with = "uuid::serde::braced")]
/// id: uuid::Uuid,
/// }
///
/// #[derive(serde_derive::Serialize, serde_derive::Deserialize)]
/// struct StructB {
/// // This will be serialized as uuid::fmt::Urn and deserialize from all valid formats
/// #[serde(serialize_with = "uuid::serde::braced::serialize")]
/// id: uuid::Uuid,
/// }
/// ```
pub mod braced {
use serde::{de, Deserialize};
use crate::parser::parse_braced;
use super::ExpectedFormat;
/// Serialize from a [`Uuid`] as a `uuid::fmt::Braced`
///
/// [`Uuid`]: ../../struct.Uuid.html
///
/// # Example
///
/// ```rust
/// #[derive(serde_derive::Serialize)]
/// struct Struct {
/// // This will be serialize as uuid::fmt::Braced
/// #[serde(serialize_with = "uuid::serde::braced::serialize")]
/// id: uuid::Uuid,
/// }
///
/// ```
pub fn serialize<S>(u: &crate::Uuid, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serde::Serialize::serialize(u.as_braced(), serializer)
}
/// Deserialize a braced Uuid string as a [`Uuid`]
///
/// [`Uuid`]: ../../struct.Uuid.html
pub fn deserialize<'de, D>(deserializer: D) -> Result<crate::Uuid, D::Error>
where
D: serde::Deserializer<'de>,
{
let s = <&str as Deserialize>::deserialize(deserializer)?;
let bytes = parse_braced(s.as_bytes()).map_err(|_| {
de::Error::invalid_value(de::Unexpected::Str(s), &ExpectedFormat::Braced)
})?;
Ok(crate::Uuid::from_bytes(bytes))
}
#[cfg(test)]
mod tests {
use serde::de::{self, Error};
use serde_test::{Readable, Token};
use crate::{external::serde_support::ExpectedFormat, Uuid};
const HYPHENATED_UUID_STR: &'static str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
const BRACED_UUID_STR: &'static str = "{f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4}";
#[test]
fn test_serialize_as_braced() {
#[derive(serde_derive::Serialize)]
struct Struct(#[serde(with = "super")] crate::Uuid);
let u = Struct(Uuid::parse_str(HYPHENATED_UUID_STR).unwrap());
serde_test::assert_ser_tokens(
&u,
&[
Token::NewtypeStruct { name: "Struct" },
Token::Str(BRACED_UUID_STR),
],
);
}
#[test]
fn test_de_from_braced() {
#[derive(PartialEq, Debug, serde_derive::Deserialize)]
struct Struct(#[serde(with = "super")] crate::Uuid);
let s = Struct(HYPHENATED_UUID_STR.parse().unwrap());
serde_test::assert_de_tokens::<Struct>(
&s,
&[
Token::TupleStruct {
name: "Struct",
len: 1,
},
Token::BorrowedStr(BRACED_UUID_STR),
Token::TupleStructEnd,
],
);
}
#[test]
fn test_de_reject_hypenated() {
#[derive(PartialEq, Debug, serde_derive::Deserialize)]
struct Struct(#[serde(with = "super")] crate::Uuid);
serde_test::assert_de_tokens_error::<Readable<Struct>>(
&[
Token::TupleStruct {
name: "Struct",
len: 1,
},
Token::BorrowedStr(HYPHENATED_UUID_STR),
Token::TupleStructEnd,
],
&format!(
"{}",
de::value::Error::invalid_value(
de::Unexpected::Str(HYPHENATED_UUID_STR),
&ExpectedFormat::Braced,
)
),
);
}
}
}
/// Serialize from a [`Uuid`] as a `uuid::fmt::Urn`
///
/// [`Uuid`]: ../../struct.Uuid.html
///
/// ## Example
///
/// ```rust
/// #[derive(serde_derive::Serialize, serde_derive::Deserialize)]
/// struct StructA {
/// // This will change both serailization and deserialization
/// #[serde(with = "uuid::serde::urn")]
/// id: uuid::Uuid,
/// }
///
/// #[derive(serde_derive::Serialize, serde_derive::Deserialize)]
/// struct StructB {
/// // This will be serialized as uuid::fmt::Urn and deserialize from all valid formats
/// #[serde(serialize_with = "uuid::serde::urn::serialize")]
/// id: uuid::Uuid,
/// }
/// ```
pub mod urn {
use serde::{de, Deserialize};
use crate::parser::parse_urn;
use super::ExpectedFormat;
/// Serialize from a [`Uuid`] as a `uuid::fmt::Urn`
///
/// [`Uuid`]: ../../struct.Uuid.html
///
/// # Example
///
/// ```rust
/// #[derive(serde_derive::Serialize)]
/// struct Struct {
/// // This will be serialize as uuid::fmt::Urn
/// #[serde(serialize_with = "uuid::serde::urn::serialize")]
/// id: uuid::Uuid,
/// }
///
/// ```
pub fn serialize<S>(u: &crate::Uuid, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serde::Serialize::serialize(u.as_urn(), serializer)
}
/// Deserialize a urn Uuid string as a [`Uuid`]
///
/// [`Uuid`]: ../../struct.Uuid.html
pub fn deserialize<'de, D>(deserializer: D) -> Result<crate::Uuid, D::Error>
where
D: serde::Deserializer<'de>,
{
let s = <&str as Deserialize>::deserialize(deserializer)?;
let bytes = parse_urn(s.as_bytes())
.map_err(|_| de::Error::invalid_value(de::Unexpected::Str(s), &ExpectedFormat::Urn))?;
Ok(crate::Uuid::from_bytes(bytes))
}
#[cfg(test)]
mod tests {
use serde::de::{self, Error};
use serde_test::{Readable, Token};
use crate::{external::serde_support::ExpectedFormat, Uuid};
const HYPHENATED_UUID_STR: &'static str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
const URN_UUID_STR: &'static str = "urn:uuid:f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
#[test]
fn test_serialize_as_urn() {
#[derive(serde_derive::Serialize)]
struct Struct(#[serde(with = "super")] crate::Uuid);
let u = Struct(Uuid::parse_str(HYPHENATED_UUID_STR).unwrap());
serde_test::assert_ser_tokens(
&u,
&[
Token::NewtypeStruct { name: "Struct" },
Token::Str(URN_UUID_STR),
],
);
}
#[test]
fn test_de_from_urn() {
#[derive(PartialEq, Debug, serde_derive::Deserialize)]
struct Struct(#[serde(with = "super")] crate::Uuid);
let s = Struct(HYPHENATED_UUID_STR.parse().unwrap());
serde_test::assert_de_tokens::<Struct>(
&s,
&[
Token::TupleStruct {
name: "Struct",
len: 1,
},
Token::BorrowedStr(URN_UUID_STR),
Token::TupleStructEnd,
],
);
}
#[test]
fn test_de_reject_hypenated() {
#[derive(PartialEq, Debug, serde_derive::Deserialize)]
struct Struct(#[serde(with = "super")] crate::Uuid);
serde_test::assert_de_tokens_error::<Readable<Struct>>(
&[
Token::TupleStruct {
name: "Struct",
len: 1,
},
Token::BorrowedStr(HYPHENATED_UUID_STR),
Token::TupleStructEnd,
],
&format!(
"{}",
de::value::Error::invalid_value(
de::Unexpected::Str(HYPHENATED_UUID_STR),
&ExpectedFormat::Urn,
)
),
);
}
}
}
#[cfg(test)]
mod serde_tests {
use super::*;
use serde_test::{Compact, Configure, Readable, Token};
#[test]
fn test_serialize_readable_string() {
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_deserialize_readable_compact() {
let uuid_bytes = b"F9168C5E-CEB2-4F";
let u = Uuid::from_slice(uuid_bytes).unwrap();
serde_test::assert_de_tokens(
&u.readable(),
&[
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,
],
);
}
#[test]
fn test_deserialize_readable_bytes() {
let uuid_bytes = b"F9168C5E-CEB2-4F";
let u = Uuid::from_slice(uuid_bytes).unwrap();
serde_test::assert_de_tokens(&u.readable(), &[serde_test::Token::Bytes(uuid_bytes)]);
}
#[test]
fn test_serialize_hyphenated() {
let uuid_str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
let u = Uuid::parse_str(uuid_str).unwrap();
serde_test::assert_ser_tokens(&u.hyphenated(), &[Token::Str(uuid_str)]);
}
#[test]
fn test_serialize_simple() {
let uuid_str = "f9168c5eceb24faab6bf329bf39fa1e4";
let u = Uuid::parse_str(uuid_str).unwrap();
serde_test::assert_ser_tokens(&u.simple(), &[Token::Str(uuid_str)]);
}
#[test]
fn test_serialize_urn() {
let uuid_str = "urn:uuid:f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
let u = Uuid::parse_str(uuid_str).unwrap();
serde_test::assert_ser_tokens(&u.urn(), &[Token::Str(uuid_str)]);
}
#[test]
fn test_serialize_braced() {
let uuid_str = "{f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4}";
let u = Uuid::parse_str(uuid_str).unwrap();
serde_test::assert_ser_tokens(&u.braced(), &[Token::Str(uuid_str)]);
}
#[test]
fn test_serialize_non_human_readable() {
let uuid_bytes = b"F9168C5E-CEB2-4F";
let u = Uuid::from_slice(uuid_bytes).unwrap();
serde_test::assert_tokens(
&u.compact(),
&[serde_test::Token::Bytes(&[
70, 57, 49, 54, 56, 67, 53, 69, 45, 67, 69, 66, 50, 45, 52, 70,
])],
);
}
#[test]
fn test_de_failure() {
serde_test::assert_de_tokens_error::<Readable<Uuid>>(
&[Token::Str("hello_world")],
"UUID parsing failed: invalid character: expected an optional prefix of `urn:uuid:` followed by [0-9a-fA-F-], found `h` at 1",
);
serde_test::assert_de_tokens_error::<Compact<Uuid>>(
&[Token::Bytes(b"hello_world")],
"UUID parsing failed: invalid length: expected 16 bytes, found 11",
);
}
#[test]
fn test_serde_non_nil_uuid() {
let uuid_str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
let uuid = Uuid::parse_str(uuid_str).unwrap();
let non_nil_uuid = NonNilUuid::try_from(uuid).unwrap();
serde_test::assert_ser_tokens(&non_nil_uuid.readable(), &[Token::Str(uuid_str)]);
serde_test::assert_de_tokens(&non_nil_uuid.readable(), &[Token::Str(uuid_str)]);
}
}

View File

@@ -0,0 +1,48 @@
// 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::{non_nil::NonNilUuid, Uuid};
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))
}
}
impl slog::Value for NonNilUuid {
fn serialize(
&self,
record: &slog::Record<'_>,
key: slog::Key,
serializer: &mut dyn slog::Serializer,
) -> Result<(), slog::Error> {
Uuid::from(*self).serialize(record, key, serializer)
}
}
#[cfg(test)]
mod tests {
use crate::tests::new;
use slog::{crit, Drain};
#[test]
fn test_slog_kv() {
let root = slog::Logger::root(slog::Discard.fuse(), slog::o!());
let u1 = new();
crit!(root, "test"; "u1" => u1);
}
}

1162
vendor/uuid/src/fmt.rs vendored Normal file

File diff suppressed because it is too large Load Diff

1744
vendor/uuid/src/lib.rs vendored Normal file

File diff suppressed because it is too large Load Diff

118
vendor/uuid/src/macros.rs vendored Normal file
View File

@@ -0,0 +1,118 @@
macro_rules! define_uuid_macro {
{$(#[$doc:meta])*} => {
$(#[$doc])*
#[cfg(feature = "macro-diagnostics")]
#[macro_export]
macro_rules! uuid {
($uuid:expr) => {{
const OUTPUT: $crate::Uuid = match $crate::Uuid::try_parse($uuid) {
$crate::__macro_support::Ok(u) => u,
$crate::__macro_support::Err(_) => panic!("invalid UUID"),
};
OUTPUT
}};
($uuid:literal) => {{
$crate::Uuid::from_bytes($crate::uuid_macro_internal::parse_lit!($uuid))
}};
}
$(#[$doc])*
#[cfg(not(feature = "macro-diagnostics"))]
#[macro_export]
macro_rules! uuid {
($uuid:expr) => {{
const OUTPUT: $crate::Uuid = match $crate::Uuid::try_parse($uuid) {
$crate::__macro_support::Ok(u) => u,
$crate::__macro_support::Err(_) => panic!("invalid UUID"),
};
OUTPUT
}};
}
}
}
define_uuid_macro! {
/// Parse [`Uuid`][uuid::Uuid]s from string literals at compile time.
///
/// ## Usage
///
/// This macro transforms the string literal representation of a
/// [`Uuid`][uuid::Uuid] into the bytes representation, raising a compilation
/// error if it cannot properly be parsed.
///
/// ## Examples
///
/// Setting a global constant:
///
/// ```
/// # use uuid::{uuid, Uuid};
/// pub const SCHEMA_ATTR_CLASS: Uuid = uuid!("00000000-0000-0000-0000-ffff00000000");
/// pub const SCHEMA_ATTR_UUID: Uuid = uuid!("00000000-0000-0000-0000-ffff00000001");
/// pub const SCHEMA_ATTR_NAME: Uuid = uuid!("00000000-0000-0000-0000-ffff00000002");
/// ```
///
/// Defining a local variable:
///
/// ```
/// # use uuid::uuid;
/// let uuid = uuid!("urn:uuid:F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4");
/// ```
/// Using a const variable:
/// ```
/// # use uuid::uuid;
/// const UUID_STR: &str = "12345678-1234-5678-1234-567812345678";
/// let UUID = uuid!(UUID_STR);
/// ```
///
/// ## Compilation Failures
///
/// Invalid UUIDs are rejected:
///
/// ```compile_fail
/// # use uuid::uuid;
/// let uuid = uuid!("F9168C5E-ZEB2-4FAA-B6BF-329BF39FA1E4");
/// ```
///
/// Enable the feature `macro-diagnostics` to see the error messages below.
///
/// Provides the following compilation error:
///
/// ```txt
/// error: invalid character: expected an optional prefix of `urn:uuid:` followed by [0-9a-fA-F-], found Z at 9
/// |
/// | let id = uuid!("F9168C5E-ZEB2-4FAA-B6BF-329BF39FA1E4");
/// | ^
/// ```
///
/// [uuid::Uuid]: https://docs.rs/uuid/*/uuid/struct.Uuid.html
}
// Internal macros
// These `transmute` macros are a stepping stone towards `zerocopy` integration.
// When the `zerocopy` feature is enabled, which it is in CI, the transmutes are
// checked by it
// SAFETY: Callers must ensure this call would be safe when handled by zerocopy
#[cfg(not(all(uuid_unstable, feature = "zerocopy")))]
macro_rules! unsafe_transmute_ref(
($e:expr) => { unsafe { core::mem::transmute::<&_, &_>($e) } }
);
// SAFETY: Callers must ensure this call would be safe when handled by zerocopy
#[cfg(all(uuid_unstable, feature = "zerocopy"))]
macro_rules! unsafe_transmute_ref(
($e:expr) => { zerocopy::transmute_ref!($e) }
);
// SAFETY: Callers must ensure this call would be safe when handled by zerocopy
#[cfg(not(all(uuid_unstable, feature = "zerocopy")))]
macro_rules! unsafe_transmute(
($e:expr) => { unsafe { core::mem::transmute::<_, _>($e) } }
);
// SAFETY: Callers must ensure this call would be safe when handled by zerocopy
#[cfg(all(uuid_unstable, feature = "zerocopy"))]
macro_rules! unsafe_transmute(
($e:expr) => { zerocopy::transmute!($e) }
);

14
vendor/uuid/src/md5.rs vendored Normal file
View File

@@ -0,0 +1,14 @@
#[cfg(feature = "v3")]
pub(crate) fn hash(ns: &[u8], src: &[u8]) -> [u8; 16] {
use md5::{Digest, Md5};
let mut hasher = Md5::new();
hasher.update(ns);
hasher.update(src);
let mut bytes = [0; 16];
bytes.copy_from_slice(&hasher.finalize()[..16]);
bytes
}

157
vendor/uuid/src/non_nil.rs vendored Normal file
View File

@@ -0,0 +1,157 @@
//! A wrapper type for nil UUIDs that provides a more memory-efficient
//! `Option<NonNilUuid>` representation.
use core::convert::TryFrom;
use std::{fmt, num::NonZeroU128};
use crate::{
error::{Error, ErrorKind},
Uuid,
};
/// A UUID that is guaranteed not to be the [nil UUID](https://www.ietf.org/rfc/rfc9562.html#name-nil-uuid).
///
/// This is useful for representing optional UUIDs more efficiently, as `Option<NonNilUuid>`
/// takes up the same space as `Uuid`.
///
/// Note that `Uuid`s created by the following methods are guaranteed to be non-nil:
///
/// - [`Uuid::new_v1`]
/// - [`Uuid::now_v1`]
/// - [`Uuid::new_v3`]
/// - [`Uuid::new_v4`]
/// - [`Uuid::new_v5`]
/// - [`Uuid::new_v6`]
/// - [`Uuid::now_v6`]
/// - [`Uuid::new_v7`]
/// - [`Uuid::now_v7`]
/// - [`Uuid::new_v8`]
///
/// # ABI
///
/// The `NonNilUuid` type does not yet have a stable ABI. Its representation or alignment
/// may change. It is currently only guaranteed that `NonNilUuid` and `Option<NonNilUuid>`
/// are the same size as `Uuid`.
#[repr(transparent)]
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct NonNilUuid(NonZeroU128);
impl fmt::Debug for NonNilUuid {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&Uuid::from(*self), f)
}
}
impl fmt::Display for NonNilUuid {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&Uuid::from(*self), f)
}
}
impl PartialEq<Uuid> for NonNilUuid {
fn eq(&self, other: &Uuid) -> bool {
self.get() == *other
}
}
impl PartialEq<NonNilUuid> for Uuid {
fn eq(&self, other: &NonNilUuid) -> bool {
*self == other.get()
}
}
impl NonNilUuid {
/// Creates a non-nil UUID if the value is non-nil.
pub const fn new(uuid: Uuid) -> Option<Self> {
match NonZeroU128::new(uuid.as_u128()) {
Some(non_nil) => Some(NonNilUuid(non_nil)),
None => None,
}
}
/// Creates a non-nil without checking whether the value is non-nil. This results in undefined behavior if the value is nil.
///
/// # Safety
///
/// The value must not be nil.
pub const unsafe fn new_unchecked(uuid: Uuid) -> Self {
NonNilUuid(unsafe { NonZeroU128::new_unchecked(uuid.as_u128()) })
}
/// Get the underlying [`Uuid`] value.
#[inline]
pub const fn get(self) -> Uuid {
Uuid::from_u128(self.0.get())
}
}
impl From<NonNilUuid> for Uuid {
/// Converts a [`NonNilUuid`] back into a [`Uuid`].
///
/// # Examples
/// ```
/// # use std::convert::TryFrom;
/// # use uuid::{NonNilUuid, Uuid};
/// let uuid = Uuid::from_u128(0x0123456789abcdef0123456789abcdef);
/// let non_nil = NonNilUuid::try_from(uuid).unwrap();
/// let uuid_again = Uuid::from(non_nil);
///
/// assert_eq!(uuid, uuid_again);
/// ```
fn from(non_nil: NonNilUuid) -> Self {
Uuid::from_u128(non_nil.0.get())
}
}
impl TryFrom<Uuid> for NonNilUuid {
type Error = Error;
/// Attempts to convert a [`Uuid`] into a [`NonNilUuid`].
///
/// # Examples
/// ```
/// # use std::convert::TryFrom;
/// # use uuid::{NonNilUuid, Uuid};
/// let uuid = Uuid::from_u128(0x0123456789abcdef0123456789abcdef);
/// let non_nil = NonNilUuid::try_from(uuid).unwrap();
/// ```
fn try_from(uuid: Uuid) -> Result<Self, Self::Error> {
NonZeroU128::new(uuid.as_u128())
.map(Self)
.ok_or(Error(ErrorKind::Nil))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_non_nil_with_option_size() {
assert_eq!(
std::mem::size_of::<Option<NonNilUuid>>(),
std::mem::size_of::<Uuid>()
);
}
#[test]
fn test_non_nil() {
let uuid = Uuid::from_u128(0x0123456789abcdef0123456789abcdef);
assert_eq!(Uuid::from(NonNilUuid::try_from(uuid).unwrap()), uuid);
assert_eq!(NonNilUuid::new(uuid).unwrap(), uuid);
assert_eq!(unsafe { NonNilUuid::new_unchecked(uuid) }, uuid);
assert!(NonNilUuid::try_from(Uuid::nil()).is_err());
assert!(NonNilUuid::new(Uuid::nil()).is_none());
}
#[test]
fn test_non_nil_formatting() {
let uuid = Uuid::from_u128(0x0123456789abcdef0123456789abcdef);
let non_nil = NonNilUuid::try_from(uuid).unwrap();
assert_eq!(format!("{uuid}"), format!("{non_nil}"));
assert_eq!(format!("{uuid:?}"), format!("{non_nil:?}"));
}
}

574
vendor/uuid/src/parser.rs vendored Normal file
View File

@@ -0,0 +1,574 @@
// 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
use crate::{
error::*,
std::{convert::TryFrom, str},
Uuid,
};
#[cfg(feature = "std")]
use crate::std::string::String;
impl str::FromStr for Uuid {
type Err = Error;
fn from_str(uuid_str: &str) -> Result<Self, Self::Err> {
Uuid::parse_str(uuid_str)
}
}
impl TryFrom<&'_ str> for Uuid {
type Error = Error;
fn try_from(uuid_str: &'_ str) -> Result<Self, Self::Error> {
Uuid::parse_str(uuid_str)
}
}
#[cfg(feature = "std")]
impl TryFrom<String> for Uuid {
type Error = Error;
fn try_from(uuid_str: String) -> Result<Self, Self::Error> {
Uuid::try_from(uuid_str.as_ref())
}
}
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,
/// Microsoft GUID) are supported by this parsing function.
///
/// Prefer [`try_parse`] unless you need detailed user-facing diagnostics.
/// This method will be eventually deprecated in favor of `try_parse`.
///
/// # Examples
///
/// Parse a hyphenated UUID:
///
/// ```
/// # use uuid::{Uuid, Version, Variant};
/// # fn main() -> Result<(), uuid::Error> {
/// let uuid = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000")?;
///
/// assert_eq!(Some(Version::Random), uuid.get_version());
/// assert_eq!(Variant::RFC4122, uuid.get_variant());
/// # Ok(())
/// # }
/// ```
///
/// [`try_parse`]: #method.try_parse
pub fn parse_str(input: &str) -> Result<Uuid, Error> {
try_parse(input.as_bytes())
.map(Uuid::from_bytes)
.map_err(InvalidUuid::into_err)
}
/// Parses a `Uuid` from a string of hexadecimal digits with optional
/// hyphens.
///
/// This function is similar to [`parse_str`], in fact `parse_str` shares
/// the same underlying parser. The difference is that if `try_parse`
/// fails, it won't generate very useful error messages. The `parse_str`
/// function will eventually be deprecated in favor of `try_parse`.
///
/// To parse a UUID from a byte stream instead of a UTF8 string, see
/// [`try_parse_ascii`].
///
/// # Examples
///
/// Parse a hyphenated UUID:
///
/// ```
/// # use uuid::{Uuid, Version, Variant};
/// # fn main() -> Result<(), uuid::Error> {
/// let uuid = Uuid::try_parse("550e8400-e29b-41d4-a716-446655440000")?;
///
/// assert_eq!(Some(Version::Random), uuid.get_version());
/// assert_eq!(Variant::RFC4122, uuid.get_variant());
/// # Ok(())
/// # }
/// ```
///
/// [`parse_str`]: #method.parse_str
/// [`try_parse_ascii`]: #method.try_parse_ascii
pub const fn try_parse(input: &str) -> Result<Uuid, Error> {
Self::try_parse_ascii(input.as_bytes())
}
/// Parses a `Uuid` from a string of hexadecimal digits with optional
/// hyphens.
///
/// The input is expected to be a string of ASCII characters. This method
/// can be more convenient than [`try_parse`] if the UUID is being
/// parsed from a byte stream instead of from a UTF8 string.
///
/// # Examples
///
/// Parse a hyphenated UUID:
///
/// ```
/// # use uuid::{Uuid, Version, Variant};
/// # fn main() -> Result<(), uuid::Error> {
/// let uuid = Uuid::try_parse_ascii(b"550e8400-e29b-41d4-a716-446655440000")?;
///
/// assert_eq!(Some(Version::Random), uuid.get_version());
/// assert_eq!(Variant::RFC4122, uuid.get_variant());
/// # Ok(())
/// # }
/// ```
///
/// [`try_parse`]: #method.try_parse
pub const fn try_parse_ascii(input: &[u8]) -> Result<Uuid, Error> {
match try_parse(input) {
Ok(bytes) => Ok(Uuid::from_bytes(bytes)),
// If parsing fails then we don't know exactly what went wrong
// In this case, we just return a generic error
Err(_) => Err(Error(ErrorKind::ParseOther)),
}
}
}
const fn try_parse(input: &'_ [u8]) -> Result<[u8; 16], InvalidUuid<'_>> {
match (input.len(), input) {
// Inputs of 32 bytes must be a non-hyphenated UUID
(32, s) => parse_simple(s),
// Hyphenated UUIDs may be wrapped in various ways:
// - `{UUID}` for braced UUIDs
// - `urn:uuid:UUID` for URNs
// - `UUID` for a regular hyphenated UUID
(36, s)
| (38, [b'{', s @ .., b'}'])
| (45, [b'u', b'r', b'n', b':', b'u', b'u', b'i', b'd', b':', s @ ..]) => {
parse_hyphenated(s)
}
// Any other shaped input is immediately invalid
_ => Err(InvalidUuid(input)),
}
}
#[inline]
#[allow(dead_code)]
pub(crate) const fn parse_braced(input: &'_ [u8]) -> Result<[u8; 16], InvalidUuid<'_>> {
if let (38, [b'{', s @ .., b'}']) = (input.len(), input) {
parse_hyphenated(s)
} else {
Err(InvalidUuid(input))
}
}
#[inline]
#[allow(dead_code)]
pub(crate) const fn parse_urn(input: &'_ [u8]) -> Result<[u8; 16], InvalidUuid<'_>> {
if let (45, [b'u', b'r', b'n', b':', b'u', b'u', b'i', b'd', b':', s @ ..]) =
(input.len(), input)
{
parse_hyphenated(s)
} else {
Err(InvalidUuid(input))
}
}
#[inline]
pub(crate) const fn parse_simple(s: &'_ [u8]) -> Result<[u8; 16], InvalidUuid<'_>> {
// This length check here removes all other bounds
// checks in this function
if s.len() != 32 {
return Err(InvalidUuid(s));
}
let mut buf: [u8; 16] = [0; 16];
let mut i = 0;
while i < 16 {
// Convert a two-char hex value (like `A8`)
// into a byte (like `10101000`)
let h1 = HEX_TABLE[s[i * 2] as usize];
let h2 = HEX_TABLE[s[i * 2 + 1] as usize];
// We use `0xff` as a sentinel value to indicate
// an invalid hex character sequence (like the letter `G`)
if h1 | h2 == 0xff {
return Err(InvalidUuid(s));
}
// The upper nibble needs to be shifted into position
// to produce the final byte value
buf[i] = SHL4_TABLE[h1 as usize] | h2;
i += 1;
}
Ok(buf)
}
#[inline]
pub(crate) const fn parse_hyphenated(s: &'_ [u8]) -> Result<[u8; 16], InvalidUuid<'_>> {
// This length check here removes all other bounds
// checks in this function
if s.len() != 36 {
return Err(InvalidUuid(s));
}
// We look at two hex-encoded values (4 chars) at a time because
// that's the size of the smallest group in a hyphenated UUID.
// The indexes we're interested in are:
//
// uuid : 936da01f-9abd-4d9d-80c7-02af85c822a8
// | | || || || || | |
// hyphens : | | 8| 13| 18| 23| | |
// positions: 0 4 9 14 19 24 28 32
// First, ensure the hyphens appear in the right places
match [s[8], s[13], s[18], s[23]] {
[b'-', b'-', b'-', b'-'] => {}
_ => return Err(InvalidUuid(s)),
}
let positions: [u8; 8] = [0, 4, 9, 14, 19, 24, 28, 32];
let mut buf: [u8; 16] = [0; 16];
let mut j = 0;
while j < 8 {
let i = positions[j];
// The decoding here is the same as the simple case
// We're just dealing with two values instead of one
let h1 = HEX_TABLE[s[i as usize] as usize];
let h2 = HEX_TABLE[s[(i + 1) as usize] as usize];
let h3 = HEX_TABLE[s[(i + 2) as usize] as usize];
let h4 = HEX_TABLE[s[(i + 3) as usize] as usize];
if h1 | h2 | h3 | h4 == 0xff {
return Err(InvalidUuid(s));
}
buf[j * 2] = SHL4_TABLE[h1 as usize] | h2;
buf[j * 2 + 1] = SHL4_TABLE[h3 as usize] | h4;
j += 1;
}
Ok(buf)
}
const HEX_TABLE: &[u8; 256] = &{
let mut buf = [0; 256];
let mut i: u8 = 0;
loop {
buf[i as usize] = match i {
b'0'..=b'9' => i - b'0',
b'a'..=b'f' => i - b'a' + 10,
b'A'..=b'F' => i - b'A' + 10,
_ => 0xff,
};
if i == 255 {
break buf;
}
i += 1
}
};
const SHL4_TABLE: &[u8; 256] = &{
let mut buf = [0; 256];
let mut i: u8 = 0;
loop {
buf[i as usize] = i.wrapping_shl(4);
if i == 255 {
break buf;
}
i += 1;
}
};
#[cfg(test)]
mod tests {
use super::*;
use crate::{std::string::ToString, tests::new};
#[test]
fn test_parse_uuid_v4_valid() {
let from_hyphenated = Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8").unwrap();
let from_simple = Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c8").unwrap();
let from_urn = Uuid::parse_str("urn:uuid:67e55044-10b1-426f-9247-bb680e5fe0c8").unwrap();
let from_guid = Uuid::parse_str("{67e55044-10b1-426f-9247-bb680e5fe0c8}").unwrap();
assert_eq!(from_hyphenated, from_simple);
assert_eq!(from_hyphenated, from_urn);
assert_eq!(from_hyphenated, from_guid);
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());
assert!(Uuid::parse_str("{6d93bade-bd9f-4e13-8914-9474e1e3567b}").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
);
}
#[test]
fn test_parse_uuid_v4_invalid() {
// Invalid
assert_eq!(
Uuid::parse_str(""),
Err(Error(ErrorKind::ParseSimpleLength { len: 0 }))
);
assert_eq!(
Uuid::parse_str("!"),
Err(Error(ErrorKind::ParseChar {
character: '!',
index: 1,
}))
);
assert_eq!(
Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E45"),
Err(Error(ErrorKind::ParseGroupLength {
group: 4,
len: 13,
index: 25,
}))
);
assert_eq!(
Uuid::parse_str("F9168C5E-CEB2-4faa-BBF-329BF39FA1E4"),
Err(Error(ErrorKind::ParseGroupLength {
group: 3,
len: 3,
index: 20,
}))
);
assert_eq!(
Uuid::parse_str("F9168C5E-CEB2-4faa-BGBF-329BF39FA1E4"),
Err(Error(ErrorKind::ParseChar {
character: 'G',
index: 21,
}))
);
assert_eq!(
Uuid::parse_str("F9168C5E-CEB2F4faaFB6BFF329BF39FA1E4"),
Err(Error(ErrorKind::ParseGroupCount { count: 2 }))
);
assert_eq!(
Uuid::parse_str("F9168C5E-CEB2-4faaFB6BFF329BF39FA1E4"),
Err(Error(ErrorKind::ParseGroupCount { count: 3 }))
);
assert_eq!(
Uuid::parse_str("F9168C5E-CEB2-4faa-B6BFF329BF39FA1E4"),
Err(Error(ErrorKind::ParseGroupCount { count: 4 }))
);
assert_eq!(
Uuid::parse_str("F9168C5E-CEB2-4faa"),
Err(Error(ErrorKind::ParseGroupCount { count: 3 }))
);
assert_eq!(
Uuid::parse_str("F9168C5E-CEB2-4faaXB6BFF329BF39FA1E4"),
Err(Error(ErrorKind::ParseChar {
character: 'X',
index: 19,
}))
);
assert_eq!(
Uuid::parse_str("{F9168C5E-CEB2-4faa9B6BFF329BF39FA1E41"),
Err(Error(ErrorKind::ParseChar {
character: '{',
index: 1,
}))
);
assert_eq!(
Uuid::parse_str("{F9168C5E-CEB2-4faa9B6BFF329BF39FA1E41}"),
Err(Error(ErrorKind::ParseGroupCount { count: 3 }))
);
assert_eq!(
Uuid::parse_str("F9168C5E-CEB-24fa-eB6BFF32-BF39FA1E4"),
Err(Error(ErrorKind::ParseGroupLength {
group: 1,
len: 3,
index: 10,
}))
);
// // (group, found, expecting)
// //
assert_eq!(
Uuid::parse_str("01020304-1112-2122-3132-41424344"),
Err(Error(ErrorKind::ParseGroupLength {
group: 4,
len: 8,
index: 25,
}))
);
assert_eq!(
Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c"),
Err(Error(ErrorKind::ParseSimpleLength { len: 31 }))
);
assert_eq!(
Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c88"),
Err(Error(ErrorKind::ParseSimpleLength { len: 33 }))
);
assert_eq!(
Uuid::parse_str("67e5504410b1426f9247bb680e5fe0cg8"),
Err(Error(ErrorKind::ParseChar {
character: 'g',
index: 32,
}))
);
assert_eq!(
Uuid::parse_str("67e5504410b1426%9247bb680e5fe0c8"),
Err(Error(ErrorKind::ParseChar {
character: '%',
index: 16,
}))
);
assert_eq!(
Uuid::parse_str("231231212212423424324323477343246663"),
Err(Error(ErrorKind::ParseSimpleLength { len: 36 }))
);
assert_eq!(
Uuid::parse_str("{00000000000000000000000000000000}"),
Err(Error(ErrorKind::ParseGroupCount { count: 1 }))
);
assert_eq!(
Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c"),
Err(Error(ErrorKind::ParseSimpleLength { len: 31 }))
);
assert_eq!(
Uuid::parse_str("67e550X410b1426f9247bb680e5fe0cd"),
Err(Error(ErrorKind::ParseChar {
character: 'X',
index: 7,
}))
);
assert_eq!(
Uuid::parse_str("67e550-4105b1426f9247bb680e5fe0c"),
Err(Error(ErrorKind::ParseGroupCount { count: 2 }))
);
assert_eq!(
Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF1-02BF39FA1E4"),
Err(Error(ErrorKind::ParseGroupLength {
group: 3,
len: 5,
index: 20,
}))
);
assert_eq!(
Uuid::parse_str("\u{bcf3c}"),
Err(Error(ErrorKind::ParseChar {
character: '\u{bcf3c}',
index: 1
}))
);
}
#[test]
fn test_roundtrip_default() {
let uuid_orig = new();
let orig_str = uuid_orig.to_string();
let uuid_out = Uuid::parse_str(&orig_str).unwrap();
assert_eq!(uuid_orig, uuid_out);
}
#[test]
fn test_roundtrip_hyphenated() {
let uuid_orig = new();
let orig_str = uuid_orig.hyphenated().to_string();
let uuid_out = Uuid::parse_str(&orig_str).unwrap();
assert_eq!(uuid_orig, uuid_out);
}
#[test]
fn test_roundtrip_simple() {
let uuid_orig = new();
let orig_str = uuid_orig.simple().to_string();
let uuid_out = Uuid::parse_str(&orig_str).unwrap();
assert_eq!(uuid_orig, uuid_out);
}
#[test]
fn test_roundtrip_urn() {
let uuid_orig = new();
let orig_str = uuid_orig.urn().to_string();
let uuid_out = Uuid::parse_str(&orig_str).unwrap();
assert_eq!(uuid_orig, uuid_out);
}
#[test]
fn test_roundtrip_braced() {
let uuid_orig = new();
let orig_str = uuid_orig.braced().to_string();
let uuid_out = Uuid::parse_str(&orig_str).unwrap();
assert_eq!(uuid_orig, uuid_out);
}
#[test]
fn test_roundtrip_parse_urn() {
let uuid_orig = new();
let orig_str = uuid_orig.urn().to_string();
let uuid_out = Uuid::from_bytes(parse_urn(orig_str.as_bytes()).unwrap());
assert_eq!(uuid_orig, uuid_out);
}
#[test]
fn test_roundtrip_parse_braced() {
let uuid_orig = new();
let orig_str = uuid_orig.braced().to_string();
let uuid_out = Uuid::from_bytes(parse_braced(orig_str.as_bytes()).unwrap());
assert_eq!(uuid_orig, uuid_out);
}
#[test]
fn test_try_parse_ascii_non_utf8() {
assert!(Uuid::try_parse_ascii(b"67e55044-10b1-426f-9247-bb680e5\0e0c8").is_err());
}
}

311
vendor/uuid/src/rng.rs vendored Normal file
View File

@@ -0,0 +1,311 @@
#![allow(dead_code, unused_imports)] // Keeps our cfg's from becoming too convoluted in here
trait Rng {
fn u128() -> u128;
fn u64() -> u64;
fn u16() -> u16;
}
pub(crate) fn u128() -> u128 {
imp::RngImp::u128()
}
pub(crate) fn u64() -> u64 {
imp::RngImp::u64()
}
pub(crate) fn u16() -> u16 {
imp::RngImp::u16()
}
#[cfg(not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none"))))]
mod imp {
/*
Random support for non `wasm32-unknown-unknown` platforms.
*/
use super::*;
// Using `rand`
#[cfg(any(feature = "rng-rand", feature = "fast-rng"))]
pub(super) struct RngImp;
#[cfg(any(feature = "rng-rand", feature = "fast-rng"))]
impl Rng for RngImp {
fn u128() -> u128 {
rand::random()
}
fn u64() -> u64 {
rand::random()
}
fn u16() -> u16 {
rand::random()
}
}
// Using `getrandom`
#[cfg(all(not(feature = "fast-rng"), not(feature = "rng-rand")))]
pub(super) struct RngImp;
#[cfg(all(not(feature = "fast-rng"), not(feature = "rng-rand")))]
impl Rng for RngImp {
fn u128() -> u128 {
let mut bytes = [0u8; 16];
getrandom::fill(&mut bytes).unwrap_or_else(|err| {
// NB: getrandom::Error has no source; this is adequate display
panic!("could not retrieve random bytes for uuid: {}", err)
});
u128::from_ne_bytes(bytes)
}
fn u64() -> u64 {
let mut bytes = [0u8; 8];
getrandom::fill(&mut bytes).unwrap_or_else(|err| {
// NB: getrandom::Error has no source; this is adequate display
panic!("could not retrieve random bytes for uuid: {}", err)
});
u64::from_ne_bytes(bytes)
}
fn u16() -> u16 {
let mut bytes = [0u8; 2];
getrandom::fill(&mut bytes).unwrap_or_else(|err| {
// NB: getrandom::Error has no source; this is adequate display
panic!("could not retrieve random bytes for uuid: {}", err)
});
u16::from_ne_bytes(bytes)
}
}
}
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
mod imp {
/*
Random support for `wasm32-unknown-unknown`.
*/
#![allow(dead_code, unused_imports)] // Keeps our cfg's from becoming too convoluted in here
use super::*;
#[cfg(all(
not(feature = "js"),
not(feature = "rng-getrandom"),
not(feature = "rng-rand")
))]
compile_error!("to use `uuid` on `wasm32-unknown-unknown`, specify a source of randomness using one of the `js`, `rng-getrandom`, or `rng-rand` features");
// Using `rand`
#[cfg(feature = "rng-rand")]
pub(super) struct RngImp;
#[cfg(feature = "rng-rand")]
impl Rng for RngImp {
fn u128() -> u128 {
uuid_rng_internal_lib::__private::rand::random()
}
fn u64() -> u64 {
uuid_rng_internal_lib::__private::rand::random()
}
fn u16() -> u16 {
uuid_rng_internal_lib::__private::rand::random()
}
}
// Using `getrandom`
#[cfg(all(feature = "rng-getrandom", not(feature = "rng-rand")))]
pub(super) struct RngImp;
#[cfg(all(feature = "rng-getrandom", not(feature = "rng-rand")))]
impl Rng for RngImp {
fn u128() -> u128 {
let mut bytes = [0u8; 16];
uuid_rng_internal_lib::__private::getrandom::fill(&mut bytes).unwrap_or_else(|err| {
// NB: getrandom::Error has no source; this is adequate display
panic!("could not retrieve random bytes for uuid: {}", err)
});
u128::from_ne_bytes(bytes)
}
fn u64() -> u64 {
let mut bytes = [0u8; 8];
uuid_rng_internal_lib::__private::getrandom::fill(&mut bytes).unwrap_or_else(|err| {
// NB: getrandom::Error has no source; this is adequate display
panic!("could not retrieve random bytes for uuid: {}", err)
});
u64::from_ne_bytes(bytes)
}
fn u16() -> u16 {
let mut bytes = [0u8; 2];
uuid_rng_internal_lib::__private::getrandom::fill(&mut bytes).unwrap_or_else(|err| {
// NB: getrandom::Error has no source; this is adequate display
panic!("could not retrieve random bytes for uuid: {}", err)
});
u16::from_ne_bytes(bytes)
}
}
// Using WebCrypto via `wasm-bindgen`
#[cfg(all(
feature = "js",
not(feature = "rng-rand"),
not(feature = "rng-getrandom")
))]
pub(super) struct RngImp;
#[cfg(all(
feature = "js",
not(feature = "rng-rand"),
not(feature = "rng-getrandom")
))]
impl Rng for RngImp {
fn u128() -> u128 {
let mut bytes = [0u8; 16];
if !webcrypto::fill(&mut bytes) {
panic!("could not retrieve random bytes for uuid")
}
u128::from_ne_bytes(bytes)
}
fn u64() -> u64 {
let mut bytes = [0u8; 8];
if !webcrypto::fill(&mut bytes) {
panic!("could not retrieve random bytes for uuid")
}
u64::from_ne_bytes(bytes)
}
fn u16() -> u16 {
let mut bytes = [0u8; 2];
if !webcrypto::fill(&mut bytes) {
panic!("could not retrieve random bytes for uuid")
}
u16::from_ne_bytes(bytes)
}
}
#[cfg(feature = "js")]
mod webcrypto {
/*
This module preserves the stabilized behavior of `uuid` that requires the
`js` feature to enable rng on `wasm32-unknown-unknown`, which it inherited
from `getrandom` `0.2`.
Vendored from `getrandom`: https://github.com/rust-random/getrandom/blob/ce3b017fdee0233c6ecd61e68b96a84bf6f911bf/src/backends/wasm_js.rs
Copyright (c) 2018-2024 The rust-random Project Developers
Copyright (c) 2014 The Rust Project Developers
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
use wasm_bindgen::{prelude::wasm_bindgen, JsValue};
#[cfg(target_feature = "atomics")]
use core::convert::TryInto;
// Maximum buffer size allowed in `Crypto.getRandomValuesSize` is 65536 bytes.
// See https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues
const MAX_BUFFER_SIZE: usize = 65536;
#[cfg(not(target_feature = "atomics"))]
#[inline]
pub fn fill(dest: &mut [u8]) -> bool {
for chunk in dest.chunks_mut(MAX_BUFFER_SIZE) {
if get_random_values(chunk).is_err() {
return false;
}
}
true
}
#[cfg(target_feature = "atomics")]
pub fn fill(dest: &mut [u8]) -> bool {
// getRandomValues does not work with all types of WASM memory,
// so we initially write to browser memory to avoid exceptions.
let buf_len = usize::min(dest.len(), MAX_BUFFER_SIZE);
let buf_len_u32 = buf_len
.try_into()
.expect("buffer length is bounded by MAX_BUFFER_SIZE");
let buf = js_sys::Uint8Array::new_with_length(buf_len_u32);
for chunk in dest.chunks_mut(buf_len) {
let chunk_len = chunk
.len()
.try_into()
.expect("chunk length is bounded by MAX_BUFFER_SIZE");
// The chunk can be smaller than buf's length, so we call to
// JS to create a smaller view of buf without allocation.
let sub_buf = if chunk_len == buf_len_u32 {
&buf
} else {
&buf.subarray(0, chunk_len)
};
if get_random_values(sub_buf).is_err() {
return false;
}
sub_buf.copy_to(chunk);
}
true
}
#[wasm_bindgen]
extern "C" {
// Crypto.getRandomValues()
#[cfg(not(target_feature = "atomics"))]
#[wasm_bindgen(js_namespace = ["globalThis", "crypto"], js_name = getRandomValues, catch)]
fn get_random_values(buf: &mut [u8]) -> Result<(), JsValue>;
#[cfg(target_feature = "atomics")]
#[wasm_bindgen(js_namespace = ["globalThis", "crypto"], js_name = getRandomValues, catch)]
fn get_random_values(buf: &js_sys::Uint8Array) -> Result<(), JsValue>;
}
}
}

14
vendor/uuid/src/sha1.rs vendored Normal file
View File

@@ -0,0 +1,14 @@
#[cfg(feature = "v5")]
pub(crate) fn hash(ns: &[u8], src: &[u8]) -> [u8; 16] {
use sha1_smol::Sha1;
let mut hasher = Sha1::new();
hasher.update(ns);
hasher.update(src);
let mut bytes = [0; 16];
bytes.copy_from_slice(&hasher.digest().bytes()[..16]);
bytes
}

1267
vendor/uuid/src/timestamp.rs vendored Normal file

File diff suppressed because it is too large Load Diff

157
vendor/uuid/src/v1.rs vendored Normal file
View File

@@ -0,0 +1,157 @@
//! The implementation for Version 1 UUIDs.
//!
//! This module is soft-deprecated. Instead of using the `Context` type re-exported here,
//! use the one from the crate root.
use crate::{Builder, Uuid};
#[deprecated(note = "use types from the crate root instead")]
pub use crate::{timestamp::context::Context, Timestamp};
impl Uuid {
/// Create a new version 1 UUID using the current system time and node ID.
///
/// This method is only available if both the `std` and `rng` features are enabled.
///
/// This method is a convenient alternative to [`Uuid::new_v1`] that uses the current system time
/// as the source timestamp.
///
/// Note that usage of this method requires the `v1`, `std`, and `rng` features of this crate
/// to be enabled.
#[cfg(all(feature = "std", feature = "rng"))]
pub fn now_v1(node_id: &[u8; 6]) -> Self {
let ts = Timestamp::now(crate::timestamp::context::shared_context());
Self::new_v1(ts, node_id)
}
/// Create a new version 1 UUID using the given timestamp and node ID.
///
/// Also see [`Uuid::now_v1`] for a convenient way to generate version 1
/// UUIDs using the current system time.
///
/// When generating [`Timestamp`]s using a [`ClockSequence`], this function
/// is only guaranteed to produce unique values if the following conditions
/// hold:
///
/// 1. The *node ID* is unique for this process,
/// 2. The *context* is shared across all threads which are generating version 1
/// 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).
///
/// 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`]. RFC 9562 requires the clock sequence
/// is seeded with a random value:
///
/// ```
/// # use uuid::{Timestamp, Context};
/// # use uuid::Uuid;
/// # fn random_seed() -> u16 { 42 }
/// let context = Context::new(random_seed());
/// let ts = Timestamp::from_unix(&context, 1497624119, 1234);
///
/// let uuid = Uuid::new_v1(ts, &[1, 2, 3, 4, 5, 6]);
///
/// assert_eq!(
/// uuid.hyphenated().to_string(),
/// "f3b4958c-52a1-11e7-802a-010203040506"
/// );
/// ```
///
/// The timestamp can also be created manually as per RFC 9562:
///
/// ```
/// # use uuid::{Uuid, Timestamp, Context, ClockSequence};
/// let context = Context::new(42);
/// let ts = Timestamp::from_gregorian(14976234442241191232, context.generate_sequence(0, 0));
///
/// let uuid = Uuid::new_v1(ts, &[1, 2, 3, 4, 5, 6]);
///
/// assert_eq!(
/// uuid.hyphenated().to_string(),
/// "b2c1ad40-45e0-1fd6-802a-010203040506"
/// );
/// ```
///
/// # References
///
/// * [UUID Version 1 in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-5.1)
///
/// [`Timestamp`]: v1/struct.Timestamp.html
/// [`ClockSequence`]: v1/trait.ClockSequence.html
/// [`Context`]: v1/struct.Context.html
pub fn new_v1(ts: Timestamp, node_id: &[u8; 6]) -> Self {
let (ticks, counter) = ts.to_gregorian();
Builder::from_gregorian_timestamp(ticks, counter, node_id).into_uuid()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{std::string::ToString, Variant, Version};
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
use wasm_bindgen_test::*;
#[test]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_test
)]
fn test_new() {
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);
assert_eq!(uuid.get_version(), Some(Version::Mac));
assert_eq!(uuid.get_variant(), Variant::RFC4122);
assert_eq!(
uuid.hyphenated().to_string(),
"20616934-4ba2-11e7-8000-010203040506"
);
let ts = uuid.get_timestamp().unwrap().to_gregorian();
assert_eq!(ts.0 - 0x01B2_1DD2_1381_4000, 14_968_545_358_129_460);
assert_eq!(Some(node), uuid.get_node_id(),);
// Ensure parsing the same UUID produces the same timestamp
let parsed = Uuid::parse_str("20616934-4ba2-11e7-8000-010203040506").unwrap();
assert_eq!(
uuid.get_timestamp().unwrap(),
parsed.get_timestamp().unwrap()
);
assert_eq!(uuid.get_node_id().unwrap(), parsed.get_node_id().unwrap(),);
}
#[test]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_test
)]
#[cfg(all(feature = "std", feature = "rng"))]
fn test_now() {
let node = [1, 2, 3, 4, 5, 6];
let uuid = Uuid::now_v1(&node);
assert_eq!(uuid.get_version(), Some(Version::Mac));
assert_eq!(uuid.get_variant(), Variant::RFC4122);
}
}

158
vendor/uuid/src/v3.rs vendored Normal file
View File

@@ -0,0 +1,158 @@
use crate::Uuid;
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.
///
/// # Examples
///
/// Generating a MD5 DNS UUID for `rust-lang.org`:
///
/// ```
/// # use uuid::{Uuid, Version};
/// let uuid = Uuid::new_v3(&Uuid::NAMESPACE_DNS, b"rust-lang.org");
///
/// assert_eq!(Some(Version::Md5), uuid.get_version());
/// ```
///
/// # References
///
/// * [UUID Version 3 in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-5.3)
/// * [Name-Based UUID Generation in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-6.5)
///
/// [`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 {
crate::Builder::from_md5_bytes(crate::md5::hash(namespace.as_bytes(), name)).into_uuid()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
use wasm_bindgen_test::*;
use crate::{std::string::ToString, Variant, Version};
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]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_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(), Some(Version::Md5));
assert_eq!(uuid.get_variant(), Variant::RFC4122);
}
}
#[test]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_test
)]
fn test_hyphenated_string() {
for &(ref ns, ref name, ref expected) in FIXTURE {
let uuid = Uuid::new_v3(*ns, name.as_bytes());
assert_eq!(uuid.hyphenated().to_string(), *expected);
}
}
}

73
vendor/uuid/src/v4.rs vendored Normal file
View File

@@ -0,0 +1,73 @@
use crate::Uuid;
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_random_bytes`][from_random_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, Version};
/// let uuid = Uuid::new_v4();
///
/// assert_eq!(Some(Version::Random), uuid.get_version());
/// ```
///
/// # References
///
/// * [UUID Version 4 in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-5.4)
///
/// [`getrandom`]: https://crates.io/crates/getrandom
/// [from_random_bytes]: struct.Builder.html#method.from_random_bytes
pub fn new_v4() -> Uuid {
// This is an optimized method for generating random UUIDs that just masks
// out the bits for the version and variant and sets them both together
Uuid::from_u128(
crate::rng::u128() & 0xFFFFFFFFFFFF4FFFBFFFFFFFFFFFFFFF | 0x40008000000000000000,
)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{Variant, Version};
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
use wasm_bindgen_test::*;
#[test]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_test
)]
fn test_new() {
let uuid = Uuid::new_v4();
assert_eq!(uuid.get_version(), Some(Version::Random));
assert_eq!(uuid.get_variant(), Variant::RFC4122);
}
#[test]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_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)
}
}

172
vendor/uuid/src/v5.rs vendored Normal file
View File

@@ -0,0 +1,172 @@
use crate::Uuid;
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.
///
/// # Examples
///
/// Generating a SHA1 DNS UUID for `rust-lang.org`:
///
/// ```
/// # use uuid::{Uuid, Version};
/// let uuid = Uuid::new_v5(&Uuid::NAMESPACE_DNS, b"rust-lang.org");
///
/// assert_eq!(Some(Version::Sha1), uuid.get_version());
/// ```
///
/// # References
///
/// * [UUID Version 5 in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-5.5)
/// * [Name-Based UUID Generation in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-6.5)
///
/// [`NAMESPACE_DNS`]: struct.Uuid.html#associatedconstant.NAMESPACE_DNS
/// [`NAMESPACE_OID`]: struct.Uuid.html#associatedconstant.NAMESPACE_OID
/// [`NAMESPACE_URL`]: struct.Uuid.html#associatedconstant.NAMESPACE_URL
/// [`NAMESPACE_X500`]: struct.Uuid.html#associatedconstant.NAMESPACE_X500
pub fn new_v5(namespace: &Uuid, name: &[u8]) -> Uuid {
crate::Builder::from_sha1_bytes(crate::sha1::hash(namespace.as_bytes(), name)).into_uuid()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
use wasm_bindgen_test::*;
use crate::{std::string::ToString, Variant, Version};
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]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_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]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_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.hyphenated().to_string(), *expected)
}
}
#[test]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_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_version(), Some(Version::Sha1));
assert_eq!(uuid.get_variant(), Variant::RFC4122);
assert_eq!(Ok(uuid), u.parse());
}
}
}

159
vendor/uuid/src/v6.rs vendored Normal file
View File

@@ -0,0 +1,159 @@
//! The implementation for Version 6 UUIDs.
//!
//! Note that you need to enable the `v6` Cargo feature
//! in order to use this module.
use crate::{Builder, Timestamp, Uuid};
impl Uuid {
/// Create a new version 6 UUID using the current system time and node ID.
///
/// This method is only available if the `std` feature is enabled.
///
/// This method is a convenient alternative to [`Uuid::new_v6`] that uses the current system time
/// as the source timestamp.
///
/// Note that usage of this method requires the `v6`, `std`, and `rng` features of this crate
/// to be enabled.
#[cfg(all(feature = "std", feature = "rng"))]
pub fn now_v6(node_id: &[u8; 6]) -> Self {
let ts = Timestamp::now(crate::timestamp::context::shared_context());
Self::new_v6(ts, node_id)
}
/// Create a new version 6 UUID using the given timestamp and a node ID.
///
/// This is similar to version 1 UUIDs, except that it is lexicographically sortable by timestamp.
///
/// Also see [`Uuid::now_v6`] for a convenient way to generate version 6
/// UUIDs using the current system time.
///
/// When generating [`Timestamp`]s using a [`ClockSequence`], this function
/// is only guaranteed to produce unique values if the following conditions
/// hold:
///
/// 1. The *node ID* is unique for this process,
/// 2. The *context* is shared across all threads which are generating version 6
/// 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 `v6` feature of this crate
/// to be enabled.
///
/// # Examples
///
/// A UUID can be created from a unix [`Timestamp`] with a
/// [`ClockSequence`]. RFC 9562 requires the clock sequence
/// is seeded with a random value:
///
/// ```rust
/// # use uuid::{Uuid, Timestamp, Context};
/// # fn random_seed() -> u16 { 42 }
/// let context = Context::new(random_seed());
/// let ts = Timestamp::from_unix(context, 1497624119, 1234);
///
/// let uuid = Uuid::new_v6(ts, &[1, 2, 3, 4, 5, 6]);
///
/// assert_eq!(
/// uuid.hyphenated().to_string(),
/// "1e752a1f-3b49-658c-802a-010203040506"
/// );
/// ```
///
/// The timestamp can also be created manually as per RFC 9562:
///
/// ```
/// # use uuid::{Uuid, Timestamp, Context, ClockSequence};
/// # fn random_seed() -> u16 { 42 }
/// let context = Context::new(random_seed());
/// let ts = Timestamp::from_gregorian(14976241191231231313, context.generate_sequence(0, 0));
///
/// let uuid = Uuid::new_v6(ts, &[1, 2, 3, 4, 5, 6]);
///
/// assert_eq!(
/// uuid.hyphenated().to_string(),
/// "fd64c041-1e91-6551-802a-010203040506"
/// );
/// ```
///
/// # References
///
/// * [UUID Version 6 in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-5.6)
///
/// [`Timestamp`]: timestamp/struct.Timestamp.html
/// [`ClockSequence`]: timestamp/trait.ClockSequence.html
/// [`Context`]: timestamp/context/struct.Context.html
pub fn new_v6(ts: Timestamp, node_id: &[u8; 6]) -> Self {
let (ticks, counter) = ts.to_gregorian();
Builder::from_sorted_gregorian_timestamp(ticks, counter, node_id).into_uuid()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{Context, Variant, Version};
use std::string::ToString;
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
use wasm_bindgen_test::*;
#[test]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_test
)]
fn test_new() {
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_v6(Timestamp::from_unix(context, time, time_fraction), &node);
assert_eq!(uuid.get_version(), Some(Version::SortMac));
assert_eq!(uuid.get_variant(), Variant::RFC4122);
assert_eq!(
uuid.hyphenated().to_string(),
"1e74ba22-0616-6934-8000-010203040506"
);
let ts = uuid.get_timestamp().unwrap().to_gregorian();
assert_eq!(ts.0 - 0x01B2_1DD2_1381_4000, 14_968_545_358_129_460);
assert_eq!(Some(node), uuid.get_node_id(),);
// Ensure parsing the same UUID produces the same timestamp
let parsed = Uuid::parse_str("1e74ba22-0616-6934-8000-010203040506").unwrap();
assert_eq!(
uuid.get_timestamp().unwrap(),
parsed.get_timestamp().unwrap()
);
assert_eq!(uuid.get_node_id().unwrap(), parsed.get_node_id().unwrap(),);
}
#[test]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_test
)]
#[cfg(all(feature = "std", feature = "rng"))]
fn test_now() {
let node = [1, 2, 3, 4, 5, 6];
let uuid = Uuid::now_v6(&node);
assert_eq!(uuid.get_version(), Some(Version::SortMac));
assert_eq!(uuid.get_variant(), Variant::RFC4122);
}
}

218
vendor/uuid/src/v7.rs vendored Normal file
View File

@@ -0,0 +1,218 @@
//! The implementation for Version 7 UUIDs.
//!
//! Note that you need to enable the `v7` Cargo feature
//! in order to use this module.
use crate::{rng, std::convert::TryInto, timestamp::Timestamp, Builder, Uuid};
impl Uuid {
/// Create a new version 7 UUID using the current time value.
///
/// This method is a convenient alternative to [`Uuid::new_v7`] that uses the current system time
/// as the source timestamp. All UUIDs generated through this method by the same process are
/// guaranteed to be ordered by their creation.
#[cfg(feature = "std")]
pub fn now_v7() -> Self {
Self::new_v7(Timestamp::now(
crate::timestamp::context::shared_context_v7(),
))
}
/// Create a new version 7 UUID using a time value and random bytes.
///
/// When the `std` feature is enabled, you can also use [`Uuid::now_v7`].
///
/// Note that usage of this method requires the `v7` feature of this crate
/// to be enabled.
///
/// Also see [`Uuid::now_v7`] for a convenient way to generate version 7
/// UUIDs using the current system time.
///
/// # Examples
///
/// A v7 UUID can be created from a unix [`Timestamp`] plus a 128 bit
/// random number. When supplied as such, the data will be combined
/// to ensure uniqueness and sortability at millisecond granularity.
///
/// ```rust
/// # use uuid::{Uuid, Timestamp, NoContext};
/// let ts = Timestamp::from_unix(NoContext, 1497624119, 1234);
///
/// let uuid = Uuid::new_v7(ts);
///
/// assert!(
/// uuid.hyphenated().to_string().starts_with("015cb15a-86d8-7")
/// );
/// ```
///
/// A v7 UUID can also be created with a counter to ensure batches of
/// UUIDs created together remain sortable:
///
/// ```rust
/// # use uuid::{Uuid, Timestamp, ContextV7};
/// let context = ContextV7::new();
/// let uuid1 = Uuid::new_v7(Timestamp::from_unix(&context, 1497624119, 1234));
/// let uuid2 = Uuid::new_v7(Timestamp::from_unix(&context, 1497624119, 1234));
///
/// assert!(uuid1 < uuid2);
/// ```
///
/// # References
///
/// * [UUID Version 7 in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-5.7)
pub fn new_v7(ts: Timestamp) -> Self {
let (secs, nanos) = ts.to_unix();
let millis = (secs * 1000).saturating_add(nanos as u64 / 1_000_000);
let mut counter_and_random = rng::u128();
let (mut counter, counter_bits) = ts.counter();
debug_assert!(counter_bits <= 128);
let mut counter_bits = counter_bits as u32;
// If the counter intersects the variant field then shift around it.
// This ensures that any bits set in the counter that would intersect
// the variant are still preserved
if counter_bits > 12 {
let mask = u128::MAX << (counter_bits - 12);
counter = (counter & !mask) | ((counter & mask) << 2);
counter_bits += 2;
}
counter_and_random &= u128::MAX.overflowing_shr(counter_bits).0;
counter_and_random |= counter
.overflowing_shl(128u32.saturating_sub(counter_bits))
.0;
Builder::from_unix_timestamp_millis(
millis,
&counter_and_random.to_be_bytes()[..10].try_into().unwrap(),
)
.into_uuid()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{std::string::ToString, ClockSequence, NoContext, Variant, Version};
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
use wasm_bindgen_test::*;
#[test]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_test
)]
fn test_new() {
let ts: u64 = 1645557742000;
let seconds = ts / 1000;
let nanos = ((ts % 1000) * 1_000_000) as u32;
let uuid = Uuid::new_v7(Timestamp::from_unix(NoContext, seconds, nanos));
let uustr = uuid.hyphenated().to_string();
assert_eq!(uuid.get_version(), Some(Version::SortRand));
assert_eq!(uuid.get_variant(), Variant::RFC4122);
assert!(uuid.hyphenated().to_string().starts_with("017f22e2-79b0-7"));
// Ensure parsing the same UUID produces the same timestamp
let parsed = Uuid::parse_str(uustr.as_str()).unwrap();
assert_eq!(uuid, parsed);
}
#[test]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_test
)]
#[cfg(feature = "std")]
fn test_now() {
let uuid = Uuid::now_v7();
assert_eq!(uuid.get_version(), Some(Version::SortRand));
assert_eq!(uuid.get_variant(), Variant::RFC4122);
}
#[test]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_test
)]
fn test_sorting() {
let time1: u64 = 1_496_854_535;
let time_fraction1: u32 = 812_000_000;
let time2 = time1 + 4000;
let time_fraction2 = time_fraction1;
let uuid1 = Uuid::new_v7(Timestamp::from_unix(NoContext, time1, time_fraction1));
let uuid2 = Uuid::new_v7(Timestamp::from_unix(NoContext, time2, time_fraction2));
assert!(uuid1.as_bytes() < uuid2.as_bytes());
assert!(uuid1.to_string() < uuid2.to_string());
}
#[test]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_test
)]
fn test_new_timestamp_roundtrip() {
let time: u64 = 1_496_854_535;
let time_fraction: u32 = 812_000_000;
let ts = Timestamp::from_unix(NoContext, time, time_fraction);
let uuid = Uuid::new_v7(ts);
let decoded_ts = uuid.get_timestamp().unwrap();
assert_eq!(ts.to_unix(), decoded_ts.to_unix());
}
#[test]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_test
)]
fn test_new_max_context() {
struct MaxContext;
#[cfg(test)]
impl ClockSequence for MaxContext {
type Output = u128;
fn generate_sequence(&self, _seconds: u64, _nanos: u32) -> Self::Output {
u128::MAX
}
fn usable_bits(&self) -> usize {
128
}
}
let time: u64 = 1_496_854_535;
let time_fraction: u32 = 812_000_000;
// Ensure we don't overflow here
let ts = Timestamp::from_unix(MaxContext, time, time_fraction);
let uuid = Uuid::new_v7(ts);
assert_eq!(uuid.get_version(), Some(Version::SortRand));
assert_eq!(uuid.get_variant(), Variant::RFC4122);
let decoded_ts = uuid.get_timestamp().unwrap();
assert_eq!(ts.to_unix(), decoded_ts.to_unix());
}
}

60
vendor/uuid/src/v8.rs vendored Normal file
View File

@@ -0,0 +1,60 @@
use crate::{Builder, Uuid};
impl Uuid {
/// Creates a custom UUID comprised almost entirely of user-supplied bytes.
///
/// This will inject the UUID Version at 4 bits starting at the 48th bit
/// and the Variant into 2 bits 64th bit. Any existing bits in the user-supplied bytes
/// at those locations will be overridden.
///
/// Note that usage of this method requires the `v8` feature of this crate
/// to be enabled.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::{Uuid, Version};
/// let buf: [u8; 16] = *b"abcdefghijklmnop";
/// let uuid = Uuid::new_v8(buf);
///
/// assert_eq!(Some(Version::Custom), uuid.get_version());
/// ```
///
/// # References
///
/// * [UUID Version 8 in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-5.8)
pub const fn new_v8(buf: [u8; 16]) -> Uuid {
Builder::from_custom_bytes(buf).into_uuid()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{Variant, Version};
use std::string::ToString;
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
use wasm_bindgen_test::*;
#[test]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_test
)]
fn test_new() {
let buf: [u8; 16] = [
0xf, 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x8, 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0,
];
let uuid = Uuid::new_v8(buf);
assert_eq!(uuid.get_version(), Some(Version::Custom));
assert_eq!(uuid.get_variant(), Variant::RFC4122);
assert_eq!(uuid.get_version_num(), 8);
assert_eq!(
uuid.hyphenated().to_string(),
"0f0e0d0c-0b0a-8908-8706-050403020100"
);
}
}