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

Support counters in v7 UUIDs #755

Merged
merged 11 commits into from
Jun 23, 2024
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ features = ["serde", "arbitrary", "slog", "borsh", "v1", "v3", "v4", "v5", "v6",
[package.metadata.playground]
features = ["serde", "v1", "v3", "v4", "v5", "v6", "v7", "v8"]

[lints.rust]
unexpected_cfgs = { level = "allow", check-cfg = ['cfg(uuid_unstable)'] }

[badges.is-it-maintained-issue-resolution]
repository = "uuid-rs/uuid"

Expand Down
10 changes: 6 additions & 4 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -609,9 +609,11 @@ impl Builder {
))
}

/// Creates a `Builder` for a version 7 UUID using the supplied Unix timestamp and random bytes.
/// Creates a `Builder` for a version 7 UUID using the supplied Unix timestamp and counter bytes.
///
/// This method assumes the bytes are already sufficiently random.
/// 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
///
Expand All @@ -636,10 +638,10 @@ impl Builder {
/// # Ok(())
/// # }
/// ```
pub const fn from_unix_timestamp_millis(millis: u64, random_bytes: &[u8; 10]) -> Self {
pub const fn from_unix_timestamp_millis(millis: u64, counter_random_bytes: &[u8; 10]) -> Self {
Builder(timestamp::encode_unix_timestamp_millis(
millis,
random_bytes,
counter_random_bytes,
))
}

Expand Down
10 changes: 4 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,9 @@ pub use timestamp::{context::NoContext, ClockSequence, Timestamp};
#[cfg(any(feature = "v1", feature = "v6"))]
pub use timestamp::context::Context;

#[cfg(feature = "v7")]
pub use timestamp::context::ContextV7;

#[cfg(feature = "v1")]
#[doc(hidden)]
// Soft-deprecated (Rust doesn't support deprecating re-exports)
Expand Down Expand Up @@ -901,12 +904,7 @@ impl Uuid {
let seconds = millis / 1000;
let nanos = ((millis % 1000) * 1_000_000) as u32;

Some(Timestamp {
seconds,
nanos,
#[cfg(any(feature = "v1", feature = "v6"))]
counter: 0,
})
Some(Timestamp::from_unix_time(seconds, nanos, 0))
}
_ => None,
}
Expand Down
26 changes: 23 additions & 3 deletions src/rng.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#[cfg(any(feature = "v4", feature = "v7"))]
pub(crate) fn bytes() -> [u8; 16] {
pub(crate) fn u128() -> u128 {
#[cfg(not(feature = "fast-rng"))]
{
let mut bytes = [0u8; 16];
Expand All @@ -9,7 +9,7 @@ pub(crate) fn bytes() -> [u8; 16] {
panic!("could not retrieve random bytes for uuid: {}", err)
});

bytes
u128::from_ne_bytes(bytes)
}

#[cfg(feature = "fast-rng")]
Expand All @@ -29,7 +29,27 @@ pub(crate) fn u16() -> u16 {
panic!("could not retrieve random bytes for uuid: {}", err)
});

((bytes[0] as u16) << 8) | (bytes[1] as u16)
u16::from_ne_bytes(bytes)
}

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

#[cfg(feature = "v7")]
pub(crate) fn u64() -> u64 {
#[cfg(not(feature = "fast-rng"))]
{
let mut bytes = [0u8; 8];

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)
});

u64::from_ne_bytes(bytes)
}

#[cfg(feature = "fast-rng")]
Expand Down
Loading
Loading