Skip to content

Commit

Permalink
Merge pull request #755 from uuid-rs/feat/v7-counter
Browse files Browse the repository at this point in the history
Support counters in v7 UUIDs
  • Loading branch information
KodrAus authored Jun 23, 2024
2 parents c705089 + c270b3d commit e62647f
Show file tree
Hide file tree
Showing 9 changed files with 658 additions and 210 deletions.
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

0 comments on commit e62647f

Please sign in to comment.