Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement now in wasm #630

Merged
merged 4 commits into from Oct 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 11 additions & 10 deletions .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:
Expand Down Expand Up @@ -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 }}"
Expand All @@ -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
Expand All @@ -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"
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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"
Expand All @@ -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"
37 changes: 21 additions & 16 deletions Cargo.toml
Expand Up @@ -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]
Expand Down Expand Up @@ -95,23 +95,23 @@ 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"

# 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"

# 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
Expand All @@ -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
Expand All @@ -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"

Expand All @@ -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"

Expand Down
10 changes: 3 additions & 7 deletions src/lib.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion src/macros.rs
Expand Up @@ -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))
}};
}

Expand Down
2 changes: 1 addition & 1 deletion 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();

Expand Down
8 changes: 4 additions & 4 deletions src/rng.rs
Expand Up @@ -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)
});
Expand All @@ -14,7 +14,7 @@ pub(crate) fn bytes() -> [u8; 16] {

#[cfg(feature = "fast-rng")]
{
private_rand::random()
rand::random()
}
}

Expand All @@ -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)
});
Expand All @@ -34,6 +34,6 @@ pub(crate) fn u16() -> u16 {

#[cfg(feature = "fast-rng")]
{
private_rand::random()
rand::random()
}
}
2 changes: 1 addition & 1 deletion 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();

Expand Down
39 changes: 32 additions & 7 deletions src/timestamp.rs
Expand Up @@ -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),
}
}

Expand Down Expand Up @@ -266,6 +264,33 @@ pub(crate) const fn decode_unix_timestamp_millis(uuid: &Uuid) -> u64 {
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
/// the uniqueness of timestamps.
///
Expand Down Expand Up @@ -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`.
///
Expand Down
14 changes: 12 additions & 2 deletions src/v7.rs
Expand Up @@ -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 {
Expand All @@ -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.
Expand Down Expand Up @@ -82,6 +82,16 @@ mod tests {
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]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn test_new_v7_timestamp_roundtrip() {
Expand Down