From bf4bf3c21351bc883c70b63e5b97c76b60b07307 Mon Sep 17 00:00:00 2001 From: KodrAus Date: Wed, 5 Oct 2022 21:52:03 +0200 Subject: [PATCH 1/4] implement now in wasm --- .github/workflows/ci.yml | 21 +++++++++++---------- Cargo.toml | 37 +++++++++++++++++++++---------------- src/lib.rs | 10 +++------- src/macros.rs | 2 +- src/md5.rs | 2 +- src/rng.rs | 8 ++++---- src/sha1.rs | 2 +- src/timestamp.rs | 39 ++++++++++++++++++++++++++++++++------- src/v7.rs | 13 +++++++++++-- 9 files changed, 85 insertions(+), 49 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4a2be3c3..44fdbdc9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,8 +1,8 @@ name: Continuous integration env: - VERSION_FEATURES: "v1 v3 v4 v5 v6 v7" - STABLE_DEP_FEATURES: "serde arbitrary" + VERSION_FEATURES: "v1 v3 v4 v5 v6 v7 v8" + DEP_FEATURES: "slog serde arbitrary zerocopy" on: pull_request: @@ -65,10 +65,10 @@ jobs: run: cargo test --all-features --examples - name: Each version feature - run: cargo hack test --lib --each-feature --optional-deps $STABLE_DEP_FEATURES + run: cargo hack test --lib --each-feature - - name: All version features - run: cargo hack test --lib --each-feature --features "$VERSION_FEATURES" --optional-deps "$STABLE_DEP_FEATURES" + - name: All features + run: cargo hack test --lib --all-features msrv: name: "Tests / MSRV / OS: ${{ matrix.os }}" @@ -91,7 +91,7 @@ jobs: override: true - name: Version features - run: cargo test --features "$VERSION_FEATURES $STABLE_DEP_FEATURES" + run: cargo test --features "$VERSION_FEATURES $DEP_FEATURES" wasm: name: Tests / WebAssembly @@ -107,7 +107,7 @@ jobs: run: wasm-pack test --node - name: Version features - run: wasm-pack test --node -- --features "$VERION_FEATURES $STABLE_DEP_FEATURES js" + run: wasm-pack test --node -- --features "$VERION_FEATURES $DEP_FEATURES js" - name: Fast RNG run: wasm-pack test --node -- --features "js v4 fast-rng" @@ -151,6 +151,7 @@ jobs: with: command: build args: -Z avoid-dev-deps --target thumbv6m-none-eabi --no-default-features + - name: Version features uses: actions-rs/cargo@v1 with: @@ -216,10 +217,10 @@ jobs: run: cargo test --all-features --examples - name: Each version feature - run: cargo hack test --lib --each-feature --optional-deps $env:STABLE_DEP_FEATURES + run: cargo hack test --lib --each-feature --optional-deps $env:DEP_FEATURES - name: All version features - run: cargo hack test --lib --each-feature --features "$env:VERSION_FEATURES" --optional-deps "$env:STABLE_DEP_FEATURES" + run: cargo hack test --lib --each-feature --features "$env:VERSION_FEATURES" --optional-deps "$env:DEP_FEATURES" win-msrv: name: "Tests / MSRV / OS: Windows 2019" @@ -236,4 +237,4 @@ jobs: override: true - name: Version features - run: cargo test --features "$env:VERSION_FEATURES $env:STABLE_DEP_FEATURES" + run: cargo test --features "$env:VERSION_FEATURES $env:DEP_FEATURES" diff --git a/Cargo.toml b/Cargo.toml index 82ecc6e4..a8d8bd70 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,25 +47,25 @@ status = "actively-developed" [features] default = ["std"] std = [] -macro-diagnostics = ["private_uuid-macro-internal"] +macro-diagnostics = ["uuid-macro-internal"] # NOTE: When adding new features, check the `ci.yml` workflow .. # and include them where necessary (you can follow along with existing features) -v1 = ["private_atomic"] +v1 = ["atomic"] v3 = ["md5"] v4 = ["rng"] v5 = ["sha1"] -v6 = ["private_atomic"] -v7 = ["private_atomic", "rng"] +v6 = ["atomic"] +v7 = ["atomic", "rng"] v8 = [] -js = ["private_getrandom", "private_getrandom/js"] +js = ["wasm-bindgen", "getrandom", "getrandom/js"] -rng = ["private_getrandom"] -fast-rng = ["rng", "private_rand"] +rng = ["getrandom"] +fast-rng = ["rng", "rand"] -sha1 = ["private_sha1_smol"] -md5 = ["private_md-5"] +sha1 = ["sha1_smol"] +md5 = ["md-5"] # Public: Used in trait impls on `Uuid` [dependencies.serde] @@ -95,7 +95,7 @@ version = "0.6" # Private # Don't depend on this optional feature directly: it may change at any time # use the `rng` feature instead -[dependencies.private_getrandom] +[dependencies.getrandom] package = "getrandom" optional = true version = "0.2" @@ -103,7 +103,7 @@ version = "0.2" # Private # Don't depend on this optional feature directly: it may change at any time # use the `fast-rng` feature instead -[dependencies.private_rand] +[dependencies.rand] package = "rand" optional = true version = "0.8" @@ -111,7 +111,7 @@ version = "0.8" # Private # Don't depend on this optional feature directly: it may change at any time # Use the `md5` feature instead -[dependencies.private_md-5] +[dependencies.md-5] package = "md-5" default-features = false optional = true @@ -120,7 +120,7 @@ version = "0.10" # Private # Don't depend on this optional feature directly: it may change at any time # Use the `sha1` feature instead -[dependencies.private_sha1_smol] +[dependencies.sha1_smol] package = "sha1_smol" default-features = false optional = true @@ -129,18 +129,23 @@ version = "1" # Public: Re-exported # Don't depend on this optional feature directly: it may change at any time # Use the `macro-diagnostics` feature instead -[dependencies.private_uuid-macro-internal] +[dependencies.uuid-macro-internal] package = "uuid-macro-internal" version = "1.1.2" path = "macros" optional = true -[dependencies.private_atomic] +[dependencies.atomic] package = "atomic" default-features = false optional = true version = "0.5" +[dependencies.wasm-bindgen] +package = "wasm-bindgen" +version = "0.2" +optional = true + [dev-dependencies.bincode] version = "1.0" @@ -153,7 +158,7 @@ version = "1.0" [dev-dependencies.serde_test] version = "1.0.56" -[target.'cfg(target_arch = "wasm32")'.dev-dependencies.wasm-bindgen-lib] +[target.'cfg(target_arch = "wasm32")'.dev-dependencies.wasm-bindgen] package = "wasm-bindgen" version = "0.2" diff --git a/src/lib.rs b/src/lib.rs index 1bea67ee..22398679 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -215,11 +215,7 @@ extern crate std; #[macro_use] extern crate core as std; -// Check that unstable features are accompanied by a the `uuid_unstable` cfg -#[cfg(all(not(uuid_unstable), feature = "zerocopy"))] -compile_error!("The `zerocopy` feature is unstable and may break between releases. Please also pass `RUSTFLAGS=\"--cfg uuid_unstable\"` to allow it."); - -#[cfg(feature = "zerocopy")] +#[cfg(all(uuid_unstable, feature = "zerocopy"))] use zerocopy::{AsBytes, FromBytes, Unaligned}; mod builder; @@ -267,7 +263,7 @@ mod macros; extern crate alloc; #[doc(hidden)] #[cfg(feature = "macro-diagnostics")] -pub extern crate private_uuid_macro_internal; +pub extern crate uuid_macro_internal; use crate::std::convert; @@ -421,7 +417,7 @@ pub enum Variant { /// /// The `Uuid` type is always guaranteed to be have the same ABI as [`Bytes`]. #[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)] -#[cfg_attr(feature = "zerocopy", derive(AsBytes, FromBytes, Unaligned))] +#[cfg_attr(all(uuid_unstable, feature = "zerocopy"), derive(AsBytes, FromBytes, Unaligned))] #[repr(transparent)] pub struct Uuid(Bytes); diff --git a/src/macros.rs b/src/macros.rs index 7136718a..de200486 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -5,7 +5,7 @@ macro_rules! define_uuid_macro { #[macro_export] macro_rules! uuid { ($uuid:literal) => {{ - $crate::Uuid::from_bytes($crate::private_uuid_macro_internal::parse_lit!($uuid)) + $crate::Uuid::from_bytes($crate::uuid_macro_internal::parse_lit!($uuid)) }}; } diff --git a/src/md5.rs b/src/md5.rs index cb6e7907..fce5d9b8 100644 --- a/src/md5.rs +++ b/src/md5.rs @@ -1,6 +1,6 @@ #[cfg(feature = "v3")] pub(crate) fn hash(ns: &[u8], src: &[u8]) -> [u8; 16] { - use private_md_5::{Digest, Md5}; + use md_5::{Digest, Md5}; let mut hasher = Md5::new(); diff --git a/src/rng.rs b/src/rng.rs index 2df10307..dcfbb8d6 100644 --- a/src/rng.rs +++ b/src/rng.rs @@ -4,7 +4,7 @@ pub(crate) fn bytes() -> [u8; 16] { { let mut bytes = [0u8; 16]; - private_getrandom::getrandom(&mut bytes).unwrap_or_else(|err| { + getrandom::getrandom(&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) }); @@ -14,7 +14,7 @@ pub(crate) fn bytes() -> [u8; 16] { #[cfg(feature = "fast-rng")] { - private_rand::random() + rand::random() } } @@ -24,7 +24,7 @@ pub(crate) fn u16() -> u16 { { let mut bytes = [0u8; 2]; - private_getrandom::getrandom(&mut bytes).unwrap_or_else(|err| { + getrandom::getrandom(&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) }); @@ -34,6 +34,6 @@ pub(crate) fn u16() -> u16 { #[cfg(feature = "fast-rng")] { - private_rand::random() + rand::random() } } diff --git a/src/sha1.rs b/src/sha1.rs index ac4644a6..14ca302f 100644 --- a/src/sha1.rs +++ b/src/sha1.rs @@ -1,6 +1,6 @@ #[cfg(feature = "v5")] pub(crate) fn hash(ns: &[u8], src: &[u8]) -> [u8; 16] { - use private_sha1_smol::Sha1; + use sha1_smol::Sha1; let mut hasher = Sha1::new(); diff --git a/src/timestamp.rs b/src/timestamp.rs index 532ba8ee..3756321b 100644 --- a/src/timestamp.rs +++ b/src/timestamp.rs @@ -60,15 +60,13 @@ impl Timestamp { let _ = context; } - let dur = std::time::SystemTime::UNIX_EPOCH - .elapsed() - .expect("Getting elapsed time since UNIX_EPOCH. If this fails, we've somehow violated causality"); + let (seconds, nanos) = now(); Timestamp { - seconds: dur.as_secs(), - nanos: dur.subsec_nanos(), + seconds, + nanos, #[cfg(any(feature = "v1", feature = "v6"))] - counter: context.generate_sequence(dur.as_secs(), dur.subsec_nanos()), + counter: context.generate_sequence(seconds, nanos), } } @@ -266,6 +264,33 @@ pub(crate) const fn decode_unix_timestamp_millis(uuid: &Uuid) -> u64 { millis } +#[cfg(all(feature = "std", target_arch = "wasm32"))] +fn now() -> (u64, u32) { + use wasm_bindgen::prelude::*; + + #[wasm_bindgen] + extern "C" { + #[wasm_bindgen(js_namespace = Date)] + fn now() -> f64; + } + + let now = now(); + + let secs = (now / 1_000.0) as u64; + let nanos = ((now % 1_000.0) * 1_000_000.0) as u32; + + dbg!((secs, nanos)) +} + +#[cfg(all(feature = "std", not(target_arch = "wasm32")))] +fn now() -> (u64, u32) { + let dur = std::time::SystemTime::UNIX_EPOCH + .elapsed() + .expect("Getting elapsed time since UNIX_EPOCH. If this fails, we've somehow violated causality"); + + (dur.as_secs(), dur.subsec_nanos()) +} + /// A counter that can be used by version 1 and version 6 UUIDs to support /// the uniqueness of timestamps. /// @@ -294,7 +319,7 @@ pub mod context { use super::ClockSequence; #[cfg(any(feature = "v1", feature = "v6"))] - use private_atomic::{Atomic, Ordering}; + use atomic::{Atomic, Ordering}; /// An empty counter that will always return the value `0`. /// diff --git a/src/v7.rs b/src/v7.rs index 947a350a..f3fde529 100644 --- a/src/v7.rs +++ b/src/v7.rs @@ -3,7 +3,7 @@ //! Note that you need to enable the `v7` Cargo feature //! in order to use this module. -use crate::{rng, timestamp::Timestamp, Builder, NoContext, Uuid}; +use crate::{rng, timestamp::Timestamp, Builder, Uuid}; use core::convert::TryInto; impl Uuid { @@ -13,7 +13,7 @@ impl Uuid { /// as the source timestamp. #[cfg(feature = "std")] pub fn now_v7() -> Self { - Self::new_v7(Timestamp::now(NoContext)) + Self::new_v7(Timestamp::now(crate::NoContext)) } /// Create a new version 7 UUID using a time value and random bytes. @@ -82,6 +82,15 @@ mod tests { assert_eq!(uuid, parsed); } + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn test_now_v7() { + let uuid = Uuid::now_v7(); + + assert_eq!(uuid.get_version(), Some(Version::SortRand)); + assert_eq!(uuid.get_variant(), Variant::RFC4122); + } + #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_new_v7_timestamp_roundtrip() { From fba6967b5b44e224fb2bd3faaaacba3ae74df779 Mon Sep 17 00:00:00 2001 From: KodrAus Date: Wed, 5 Oct 2022 21:57:12 +0200 Subject: [PATCH 2/4] only use wasm-bindgen in the js feature --- Cargo.toml | 2 +- src/timestamp.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a8d8bd70..25ee4c6e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -81,7 +81,7 @@ version = "2" # Public: Used in trait impls on `Uuid` [dependencies.arbitrary] optional = true -version = "=1.1.3" +version = "1.1.3" # Public (unstable): Used in `zerocopy` derive # Unstable: also need RUSTFLAGS="--cfg uuid_unstable" to work diff --git a/src/timestamp.rs b/src/timestamp.rs index 3756321b..f2ba3e2e 100644 --- a/src/timestamp.rs +++ b/src/timestamp.rs @@ -264,7 +264,7 @@ pub(crate) const fn decode_unix_timestamp_millis(uuid: &Uuid) -> u64 { millis } -#[cfg(all(feature = "std", target_arch = "wasm32"))] +#[cfg(all(feature = "std", feature = "js", target_arch = "wasm32"))] fn now() -> (u64, u32) { use wasm_bindgen::prelude::*; @@ -282,7 +282,7 @@ fn now() -> (u64, u32) { dbg!((secs, nanos)) } -#[cfg(all(feature = "std", not(target_arch = "wasm32")))] +#[cfg(all(feature = "std", any(not(feature = "js"), not(target_arch = "wasm32"))))] fn now() -> (u64, u32) { let dur = std::time::SystemTime::UNIX_EPOCH .elapsed() From 29cbcea64e57bca604f04703d4d2cd03a032c311 Mon Sep 17 00:00:00 2001 From: KodrAus Date: Wed, 5 Oct 2022 22:01:49 +0200 Subject: [PATCH 3/4] repin arbitrary --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 25ee4c6e..a8d8bd70 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -81,7 +81,7 @@ version = "2" # Public: Used in trait impls on `Uuid` [dependencies.arbitrary] optional = true -version = "1.1.3" +version = "=1.1.3" # Public (unstable): Used in `zerocopy` derive # Unstable: also need RUSTFLAGS="--cfg uuid_unstable" to work From 17837cc6d79b0c798d0071002e5355077bced008 Mon Sep 17 00:00:00 2001 From: KodrAus Date: Wed, 5 Oct 2022 22:07:38 +0200 Subject: [PATCH 4/4] only test now when std is enabled --- src/v7.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/v7.rs b/src/v7.rs index f3fde529..a5ad01a0 100644 --- a/src/v7.rs +++ b/src/v7.rs @@ -84,6 +84,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[cfg(feature = "std")] fn test_now_v7() { let uuid = Uuid::now_v7();