diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 44fdbdc9..fb2e9994 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -70,13 +70,34 @@ jobs: - name: All features run: cargo hack test --lib --all-features + stable: + name: "Tests / Stable / OS: ${{ matrix.os }}" + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: + - ubuntu-20.04 + + steps: + - name: Checkout sources + uses: actions/checkout@v2 + + - name: Install Rust toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + + - name: All features + run: cargo test --all-features + msrv: name: "Tests / MSRV / OS: ${{ matrix.os }}" runs-on: ${{ matrix.os }} strategy: matrix: os: - - macos-10.15 - ubuntu-20.04 steps: @@ -91,7 +112,7 @@ jobs: override: true - name: Version features - run: cargo test --features "$VERSION_FEATURES $DEP_FEATURES" + run: cargo test --features "$VERSION_FEATURES" wasm: name: Tests / WebAssembly diff --git a/src/builder.rs b/src/builder.rs index bf3b3611..772f1ee9 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -42,28 +42,6 @@ use crate::{error::*, timestamp, Bytes, Uuid, Variant, Version}; /// assert_eq!(Some(Version::Random), uuid.get_version()); /// assert_eq!(Variant::RFC4122, uuid.get_variant()); /// ``` -/// -/// Creating a version 7 UUID from the current system time and externally generated random bytes: -/// -/// ``` -/// # use std::convert::TryInto; -/// use std::time::{Duration, SystemTime}; -/// # fn main() -> Result<(), Box> { -/// # 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(()) -/// # } -/// ``` #[allow(missing_copy_implementations)] #[derive(Debug)] pub struct Builder(Uuid); @@ -117,6 +95,7 @@ impl Uuid { /// uuid.hyphenated().to_string(), /// ); /// ``` + #[cfg(uuid_unstable)] pub const fn max() -> Self { Uuid::from_bytes([0xFF; 16]) } @@ -619,6 +598,7 @@ impl Builder { /// Creates a `Builder` for a version 6 UUID using the supplied timestamp and node ID. /// /// This method will encode the ticks, counter, and node ID in a sortable UUID. + #[cfg(uuid_unstable)] pub const fn from_sorted_rfc4122_timestamp( ticks: u64, counter: u16, @@ -656,6 +636,7 @@ impl Builder { /// # Ok(()) /// # } /// ``` + #[cfg(uuid_unstable)] pub const fn from_unix_timestamp_millis(millis: u64, random_bytes: &[u8; 10]) -> Self { Builder(timestamp::encode_unix_timestamp_millis( millis, @@ -667,6 +648,7 @@ impl Builder { /// /// This method won't interpret the given bytes in any way, except to set the appropriate /// bits for the UUID version and variant. + #[cfg(uuid_unstable)] pub const fn from_custom_bytes(custom_bytes: Bytes) -> Self { Builder::from_bytes(custom_bytes) .with_variant(Variant::RFC4122) diff --git a/src/lib.rs b/src/lib.rs index ba1c9f7c..161b3ccd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -80,9 +80,8 @@ //! * `v3` - Version 3 UUIDs based on the MD5 hash of some data. //! * `v4` - Version 4 UUIDs with random data. //! * `v5` - Version 5 UUIDs based on the SHA1 hash of some data. -//! * `v6` - Version 6 UUIDs using a timestamp and monotonic counter. -//! * `v7` - Version 7 UUIDs using a Unix timestamp. -//! * `v8` - Version 8 UUIDs using user-defined data. +//! +//! Versions that are in draft are also supported. See the _unstable features_ section for details. //! //! This library also includes a [`Builder`] type that can be used to help construct UUIDs of any //! version without any additional dependencies or features. It's a lower-level API than [`Uuid`] @@ -115,6 +114,9 @@ //! Some features are unstable. They may be incomplete or depend on other //! unstable libraries. These include: //! +//! * `v6` - Version 6 UUIDs using a timestamp and monotonic counter. +//! * `v7` - Version 7 UUIDs using a Unix timestamp. +//! * `v8` - Version 8 UUIDs using user-defined data. //! * `zerocopy` - adds support for zero-copy deserialization using the //! `zerocopy` library. //! @@ -246,11 +248,11 @@ mod v3; mod v4; #[cfg(feature = "v5")] mod v5; -#[cfg(feature = "v6")] +#[cfg(all(uuid_unstable, feature = "v6"))] mod v6; -#[cfg(feature = "v7")] +#[cfg(all(uuid_unstable, feature = "v7"))] mod v7; -#[cfg(feature = "v8")] +#[cfg(all(uuid_unstable, feature = "v8"))] mod v8; #[cfg(feature = "md5")] @@ -293,22 +295,26 @@ pub enum Version { /// The "nil" (all zeros) UUID. Nil = 0u8, /// Version 1: Timestamp and node ID. - Mac, + Mac = 1, /// Version 2: DCE Security. - Dce, + Dce = 2, /// Version 3: MD5 hash. - Md5, + Md5 = 3, /// Version 4: Random. - Random, + Random = 4, /// Version 5: SHA-1 hash. - Sha1, + Sha1 = 5, /// Version 6: Sortable Timestamp and node ID. - SortMac, + #[cfg(uuid_unstable)] + SortMac = 6, /// Version 7: Timestamp and random. - SortRand, + #[cfg(uuid_unstable)] + SortRand = 7, /// Version 8: Custom. - Custom, + #[cfg(uuid_unstable)] + Custom = 8, /// The "max" (all ones) UUID. + #[cfg(uuid_unstable)] Max = 0xff, } @@ -551,9 +557,13 @@ impl Uuid { 3 => Some(Version::Md5), 4 => Some(Version::Random), 5 => Some(Version::Sha1), + #[cfg(uuid_unstable)] 6 => Some(Version::SortMac), + #[cfg(uuid_unstable)] 7 => Some(Version::SortRand), + #[cfg(uuid_unstable)] 8 => Some(Version::Custom), + #[cfg(uuid_unstable)] 0xf => Some(Version::Max), _ => None, } @@ -851,6 +861,7 @@ impl Uuid { } /// Tests if the UUID is max (all ones). + #[cfg(uuid_unstable)] pub const fn is_max(&self) -> bool { self.as_u128() == u128::MAX } @@ -910,11 +921,13 @@ impl Uuid { Some(Timestamp::from_rfc4122(ticks, counter)) } + #[cfg(uuid_unstable)] Some(Version::SortMac) => { let (ticks, counter) = timestamp::decode_sorted_rfc4122_timestamp(self); Some(Timestamp::from_rfc4122(ticks, counter)) } + #[cfg(uuid_unstable)] Some(Version::SortRand) => { let millis = timestamp::decode_unix_timestamp_millis(self); @@ -1100,6 +1113,7 @@ mod tests { } #[test] + #[cfg(uuid_unstable)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_max() { let max = Uuid::max(); diff --git a/src/timestamp.rs b/src/timestamp.rs index f2ba3e2e..2f95ac4e 100644 --- a/src/timestamp.rs +++ b/src/timestamp.rs @@ -190,6 +190,7 @@ pub(crate) const fn decode_rfc4122_timestamp(uuid: &Uuid) -> (u64, u16) { (ticks, counter) } +#[cfg(uuid_unstable)] pub(crate) const fn encode_sorted_rfc4122_timestamp( ticks: u64, counter: u16, @@ -213,6 +214,7 @@ pub(crate) const fn encode_sorted_rfc4122_timestamp( Uuid::from_fields(time_high, time_mid, time_low_and_version, &d4) } +#[cfg(uuid_unstable)] pub(crate) const fn decode_sorted_rfc4122_timestamp(uuid: &Uuid) -> (u64, u16) { let bytes = uuid.as_bytes(); @@ -230,6 +232,7 @@ pub(crate) const fn decode_sorted_rfc4122_timestamp(uuid: &Uuid) -> (u64, u16) { (ticks, counter) } +#[cfg(uuid_unstable)] pub(crate) const fn encode_unix_timestamp_millis(millis: u64, random_bytes: &[u8; 10]) -> Uuid { let millis_high = ((millis >> 16) & 0xFFFF_FFFF) as u32; let millis_low = (millis & 0xFFFF) as u16; @@ -251,6 +254,7 @@ pub(crate) const fn encode_unix_timestamp_millis(millis: u64, random_bytes: &[u8 Uuid::from_fields(millis_high, millis_low, random_and_version, &d4) } +#[cfg(uuid_unstable)] pub(crate) const fn decode_unix_timestamp_millis(uuid: &Uuid) -> u64 { let bytes = uuid.as_bytes();