Merge pull request #630 from KodrAus/feat/now-wasm

Implement now in wasm
This commit is contained in:
Ashley Mannix 2022-10-06 06:26:46 +10:00 committed by GitHub
commit 9fcb760b6a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 86 additions and 49 deletions

View File

@ -1,8 +1,8 @@
name: Continuous integration name: Continuous integration
env: env:
VERSION_FEATURES: "v1 v3 v4 v5 v6 v7" VERSION_FEATURES: "v1 v3 v4 v5 v6 v7 v8"
STABLE_DEP_FEATURES: "serde arbitrary" DEP_FEATURES: "slog serde arbitrary zerocopy"
on: on:
pull_request: pull_request:
@ -65,10 +65,10 @@ jobs:
run: cargo test --all-features --examples run: cargo test --all-features --examples
- name: Each version feature - 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 - name: All features
run: cargo hack test --lib --each-feature --features "$VERSION_FEATURES" --optional-deps "$STABLE_DEP_FEATURES" run: cargo hack test --lib --all-features
msrv: msrv:
name: "Tests / MSRV / OS: ${{ matrix.os }}" name: "Tests / MSRV / OS: ${{ matrix.os }}"
@ -91,7 +91,7 @@ jobs:
override: true override: true
- name: Version features - name: Version features
run: cargo test --features "$VERSION_FEATURES $STABLE_DEP_FEATURES" run: cargo test --features "$VERSION_FEATURES $DEP_FEATURES"
wasm: wasm:
name: Tests / WebAssembly name: Tests / WebAssembly
@ -107,7 +107,7 @@ jobs:
run: wasm-pack test --node run: wasm-pack test --node
- name: Version features - 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 - name: Fast RNG
run: wasm-pack test --node -- --features "js v4 fast-rng" run: wasm-pack test --node -- --features "js v4 fast-rng"
@ -151,6 +151,7 @@ jobs:
with: with:
command: build command: build
args: -Z avoid-dev-deps --target thumbv6m-none-eabi --no-default-features args: -Z avoid-dev-deps --target thumbv6m-none-eabi --no-default-features
- name: Version features - name: Version features
uses: actions-rs/cargo@v1 uses: actions-rs/cargo@v1
with: with:
@ -216,10 +217,10 @@ jobs:
run: cargo test --all-features --examples run: cargo test --all-features --examples
- name: Each version feature - 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 - 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: win-msrv:
name: "Tests / MSRV / OS: Windows 2019" name: "Tests / MSRV / OS: Windows 2019"
@ -236,4 +237,4 @@ jobs:
override: true override: true
- name: Version features - name: Version features
run: cargo test --features "$env:VERSION_FEATURES $env:STABLE_DEP_FEATURES" run: cargo test --features "$env:VERSION_FEATURES $env:DEP_FEATURES"

View File

@ -47,25 +47,25 @@ status = "actively-developed"
[features] [features]
default = ["std"] default = ["std"]
std = [] std = []
macro-diagnostics = ["private_uuid-macro-internal"] macro-diagnostics = ["uuid-macro-internal"]
# NOTE: When adding new features, check the `ci.yml` workflow .. # NOTE: When adding new features, check the `ci.yml` workflow ..
# and include them where necessary (you can follow along with existing features) # and include them where necessary (you can follow along with existing features)
v1 = ["private_atomic"] v1 = ["atomic"]
v3 = ["md5"] v3 = ["md5"]
v4 = ["rng"] v4 = ["rng"]
v5 = ["sha1"] v5 = ["sha1"]
v6 = ["private_atomic"] v6 = ["atomic"]
v7 = ["private_atomic", "rng"] v7 = ["atomic", "rng"]
v8 = [] v8 = []
js = ["private_getrandom", "private_getrandom/js"] js = ["wasm-bindgen", "getrandom", "getrandom/js"]
rng = ["private_getrandom"] rng = ["getrandom"]
fast-rng = ["rng", "private_rand"] fast-rng = ["rng", "rand"]
sha1 = ["private_sha1_smol"] sha1 = ["sha1_smol"]
md5 = ["private_md-5"] md5 = ["md-5"]
# Public: Used in trait impls on `Uuid` # Public: Used in trait impls on `Uuid`
[dependencies.serde] [dependencies.serde]
@ -95,7 +95,7 @@ version = "0.6"
# Private # Private
# Don't depend on this optional feature directly: it may change at any time # Don't depend on this optional feature directly: it may change at any time
# use the `rng` feature instead # use the `rng` feature instead
[dependencies.private_getrandom] [dependencies.getrandom]
package = "getrandom" package = "getrandom"
optional = true optional = true
version = "0.2" version = "0.2"
@ -103,7 +103,7 @@ version = "0.2"
# Private # Private
# Don't depend on this optional feature directly: it may change at any time # Don't depend on this optional feature directly: it may change at any time
# use the `fast-rng` feature instead # use the `fast-rng` feature instead
[dependencies.private_rand] [dependencies.rand]
package = "rand" package = "rand"
optional = true optional = true
version = "0.8" version = "0.8"
@ -111,7 +111,7 @@ version = "0.8"
# Private # Private
# Don't depend on this optional feature directly: it may change at any time # Don't depend on this optional feature directly: it may change at any time
# Use the `md5` feature instead # Use the `md5` feature instead
[dependencies.private_md-5] [dependencies.md-5]
package = "md-5" package = "md-5"
default-features = false default-features = false
optional = true optional = true
@ -120,7 +120,7 @@ version = "0.10"
# Private # Private
# Don't depend on this optional feature directly: it may change at any time # Don't depend on this optional feature directly: it may change at any time
# Use the `sha1` feature instead # Use the `sha1` feature instead
[dependencies.private_sha1_smol] [dependencies.sha1_smol]
package = "sha1_smol" package = "sha1_smol"
default-features = false default-features = false
optional = true optional = true
@ -129,18 +129,23 @@ version = "1"
# Public: Re-exported # Public: Re-exported
# Don't depend on this optional feature directly: it may change at any time # Don't depend on this optional feature directly: it may change at any time
# Use the `macro-diagnostics` feature instead # Use the `macro-diagnostics` feature instead
[dependencies.private_uuid-macro-internal] [dependencies.uuid-macro-internal]
package = "uuid-macro-internal" package = "uuid-macro-internal"
version = "1.1.2" version = "1.1.2"
path = "macros" path = "macros"
optional = true optional = true
[dependencies.private_atomic] [dependencies.atomic]
package = "atomic" package = "atomic"
default-features = false default-features = false
optional = true optional = true
version = "0.5" version = "0.5"
[dependencies.wasm-bindgen]
package = "wasm-bindgen"
version = "0.2"
optional = true
[dev-dependencies.bincode] [dev-dependencies.bincode]
version = "1.0" version = "1.0"
@ -153,7 +158,7 @@ version = "1.0"
[dev-dependencies.serde_test] [dev-dependencies.serde_test]
version = "1.0.56" 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" package = "wasm-bindgen"
version = "0.2" version = "0.2"

View File

@ -215,11 +215,7 @@ extern crate std;
#[macro_use] #[macro_use]
extern crate core as std; extern crate core as std;
// Check that unstable features are accompanied by a the `uuid_unstable` cfg #[cfg(all(uuid_unstable, feature = "zerocopy"))]
#[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")]
use zerocopy::{AsBytes, FromBytes, Unaligned}; use zerocopy::{AsBytes, FromBytes, Unaligned};
mod builder; mod builder;
@ -267,7 +263,7 @@ mod macros;
extern crate alloc; extern crate alloc;
#[doc(hidden)] #[doc(hidden)]
#[cfg(feature = "macro-diagnostics")] #[cfg(feature = "macro-diagnostics")]
pub extern crate private_uuid_macro_internal; pub extern crate uuid_macro_internal;
use crate::std::convert; 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`]. /// The `Uuid` type is always guaranteed to be have the same ABI as [`Bytes`].
#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)] #[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)] #[repr(transparent)]
pub struct Uuid(Bytes); pub struct Uuid(Bytes);

View File

@ -5,7 +5,7 @@ macro_rules! define_uuid_macro {
#[macro_export] #[macro_export]
macro_rules! uuid { macro_rules! uuid {
($uuid:literal) => {{ ($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))
}}; }};
} }

View File

@ -1,6 +1,6 @@
#[cfg(feature = "v3")] #[cfg(feature = "v3")]
pub(crate) fn hash(ns: &[u8], src: &[u8]) -> [u8; 16] { 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(); let mut hasher = Md5::new();

View File

@ -4,7 +4,7 @@ pub(crate) fn bytes() -> [u8; 16] {
{ {
let mut bytes = [0u8; 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 // NB: getrandom::Error has no source; this is adequate display
panic!("could not retrieve random bytes for uuid: {}", err) panic!("could not retrieve random bytes for uuid: {}", err)
}); });
@ -14,7 +14,7 @@ pub(crate) fn bytes() -> [u8; 16] {
#[cfg(feature = "fast-rng")] #[cfg(feature = "fast-rng")]
{ {
private_rand::random() rand::random()
} }
} }
@ -24,7 +24,7 @@ pub(crate) fn u16() -> u16 {
{ {
let mut bytes = [0u8; 2]; 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 // NB: getrandom::Error has no source; this is adequate display
panic!("could not retrieve random bytes for uuid: {}", err) panic!("could not retrieve random bytes for uuid: {}", err)
}); });
@ -34,6 +34,6 @@ pub(crate) fn u16() -> u16 {
#[cfg(feature = "fast-rng")] #[cfg(feature = "fast-rng")]
{ {
private_rand::random() rand::random()
} }
} }

View File

@ -1,6 +1,6 @@
#[cfg(feature = "v5")] #[cfg(feature = "v5")]
pub(crate) fn hash(ns: &[u8], src: &[u8]) -> [u8; 16] { pub(crate) fn hash(ns: &[u8], src: &[u8]) -> [u8; 16] {
use private_sha1_smol::Sha1; use sha1_smol::Sha1;
let mut hasher = Sha1::new(); let mut hasher = Sha1::new();

View File

@ -60,15 +60,13 @@ impl Timestamp {
let _ = context; let _ = context;
} }
let dur = std::time::SystemTime::UNIX_EPOCH let (seconds, nanos) = now();
.elapsed()
.expect("Getting elapsed time since UNIX_EPOCH. If this fails, we've somehow violated causality");
Timestamp { Timestamp {
seconds: dur.as_secs(), seconds,
nanos: dur.subsec_nanos(), nanos,
#[cfg(any(feature = "v1", feature = "v6"))] #[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 millis
} }
#[cfg(all(feature = "std", feature = "js", 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", any(not(feature = "js"), 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 /// A counter that can be used by version 1 and version 6 UUIDs to support
/// the uniqueness of timestamps. /// the uniqueness of timestamps.
/// ///
@ -294,7 +319,7 @@ pub mod context {
use super::ClockSequence; use super::ClockSequence;
#[cfg(any(feature = "v1", feature = "v6"))] #[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`. /// An empty counter that will always return the value `0`.
/// ///

View File

@ -3,7 +3,7 @@
//! Note that you need to enable the `v7` Cargo feature //! Note that you need to enable the `v7` Cargo feature
//! in order to use this module. //! 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; use core::convert::TryInto;
impl Uuid { impl Uuid {
@ -13,7 +13,7 @@ impl Uuid {
/// as the source timestamp. /// as the source timestamp.
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub fn now_v7() -> Self { 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. /// Create a new version 7 UUID using a time value and random bytes.
@ -82,6 +82,16 @@ mod tests {
assert_eq!(uuid, parsed); assert_eq!(uuid, parsed);
} }
#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
#[cfg(feature = "std")]
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] #[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn test_new_v7_timestamp_roundtrip() { fn test_new_v7_timestamp_roundtrip() {