mirror of
https://github.com/uuid-rs/uuid.git
synced 2025-09-29 22:10:50 +00:00
commit
d626fd5874
@ -15,15 +15,19 @@
|
||||
|
||||
use crate::{error::*, timestamp, Bytes, Uuid, Variant, Version};
|
||||
|
||||
/// A builder struct for creating a UUID.
|
||||
/// A builder for creating a UUID.
|
||||
///
|
||||
/// This type is useful if you need to mutate individual fields of a [`Uuid`]
|
||||
/// while constructing it. Since the [`Uuid`] type is `Copy`, it doesn't offer
|
||||
/// any methods to mutate in place. They live on the `Builder` instead.
|
||||
///
|
||||
/// The `Builder` type also always exposes APIs to construct [`Uuid`]s for any
|
||||
/// version without needing crate features or additional dependencies. It's a
|
||||
/// lower-level API than the methods on [`Uuid`].
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Creating a v4 UUID from externally generated bytes:
|
||||
/// Creating a version 4 UUID from externally generated random bytes:
|
||||
///
|
||||
/// ```
|
||||
/// # use uuid::{Builder, Version, Variant};
|
||||
@ -38,6 +42,28 @@ use crate::{error::*, timestamp, Bytes, Uuid, Variant, Version};
|
||||
/// assert_eq!(Some(Version::Random), uuid.get_version());
|
||||
/// assert_eq!(Variant::RFC4122, uuid.get_variant());
|
||||
/// ```
|
||||
///
|
||||
/// Creating a version 7 UUID from the current system time and externally generated random bytes:
|
||||
///
|
||||
/// ```
|
||||
/// # use std::convert::TryInto;
|
||||
/// use std::time::{Duration, SystemTime};
|
||||
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
/// # use uuid::{Builder, Uuid, Variant, Version, Timestamp, NoContext};
|
||||
/// # let rng = || [
|
||||
/// # 70, 235, 208, 238, 14, 109, 67, 201, 185, 13
|
||||
/// # ];
|
||||
/// let ts = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?;
|
||||
///
|
||||
/// let random_bytes = rng();
|
||||
///
|
||||
/// let uuid = Builder::from_unix_timestamp_millis(ts.as_millis().try_into()?, &random_bytes).into_uuid();
|
||||
///
|
||||
/// assert_eq!(Some(Version::SortRand), uuid.get_version());
|
||||
/// assert_eq!(Variant::RFC4122, uuid.get_variant());
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
#[allow(missing_copy_implementations)]
|
||||
#[derive(Debug)]
|
||||
pub struct Builder(Uuid);
|
||||
@ -543,7 +569,7 @@ impl Builder {
|
||||
Builder(Uuid::from_bytes_le(b))
|
||||
}
|
||||
|
||||
/// Creates a `Builder` for a version 1 UUID using the supplied timestamp and node id.
|
||||
/// Creates a `Builder` for a version 1 UUID using the supplied timestamp and node ID.
|
||||
pub const fn from_rfc4122_timestamp(ticks: u64, counter: u16, node_id: &[u8; 6]) -> Self {
|
||||
Builder(timestamp::encode_rfc4122_timestamp(ticks, counter, node_id))
|
||||
}
|
||||
@ -590,9 +616,9 @@ impl Builder {
|
||||
.with_version(Version::Sha1)
|
||||
}
|
||||
|
||||
/// Creates a `Builder` for a version 6 UUID using the supplied timestamp and node id.
|
||||
/// Creates a `Builder` for a version 6 UUID using the supplied timestamp and node ID.
|
||||
///
|
||||
/// This method will encode the ticks, counter, and node id in a sortable UUID.
|
||||
/// This method will encode the ticks, counter, and node ID in a sortable UUID.
|
||||
pub const fn from_sorted_rfc4122_timestamp(
|
||||
ticks: u64,
|
||||
counter: u16,
|
||||
|
65
src/lib.rs
65
src/lib.rs
@ -85,7 +85,9 @@
|
||||
//! * `v8` - Version 8 UUIDs using user-defined data.
|
||||
//!
|
||||
//! This library also includes a [`Builder`] type that can be used to help construct UUIDs of any
|
||||
//! version without any additional dependencies or features.
|
||||
//! version without any additional dependencies or features. It's a lower-level API than [`Uuid`]
|
||||
//! that can be used when you need control over implicit requirements on things like a source
|
||||
//! of randomness.
|
||||
//!
|
||||
//! ## Which UUID version should I use?
|
||||
//!
|
||||
@ -93,6 +95,8 @@
|
||||
//! to use UUIDs as database keys or need to sort them then consider version 7 (`v7`) UUIDs.
|
||||
//! Other versions should generally be avoided unless there's an existing need for them.
|
||||
//!
|
||||
//! Some UUID versions supersede others. Prefer version 6 over version 1 and version 5 over version 3.
|
||||
//!
|
||||
//! # Other features
|
||||
//!
|
||||
//! Other crate features can also be useful beyond the version support:
|
||||
@ -132,9 +136,10 @@
|
||||
//!
|
||||
//! ```toml
|
||||
//! [dependencies.uuid]
|
||||
//! version = "1"
|
||||
//! version = "1.1.2"
|
||||
//! features = [
|
||||
//! "v4",
|
||||
//! "v7",
|
||||
//! "js",
|
||||
//! ]
|
||||
//! ```
|
||||
@ -146,7 +151,7 @@
|
||||
//!
|
||||
//! ```toml
|
||||
//! [dependencies.uuid]
|
||||
//! version = "1"
|
||||
//! version = "1.1.2"
|
||||
//! default-features = false
|
||||
//! ```
|
||||
//!
|
||||
@ -163,7 +168,7 @@
|
||||
//!
|
||||
//! # Examples
|
||||
//!
|
||||
//! To parse a UUID given in the simple format and print it as a URN:
|
||||
//! Parse a UUID given in the simple format and print it as a URN:
|
||||
//!
|
||||
//! ```
|
||||
//! # use uuid::Uuid;
|
||||
@ -175,7 +180,7 @@
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! To create a new random (V4) UUID and print it out in hexadecimal form:
|
||||
//! Generate a random UUID and print it out in hexadecimal form:
|
||||
//!
|
||||
//! ```
|
||||
//! // Note that this requires the `v4` feature to be enabled.
|
||||
@ -283,9 +288,10 @@ pub type Bytes = [u8; 16];
|
||||
/// * [Version in RFC4122](https://datatracker.ietf.org/doc/html/rfc4122#section-4.1.3)
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
#[non_exhaustive]
|
||||
#[repr(u8)]
|
||||
pub enum Version {
|
||||
/// The _nil_ (all zeros) UUID.
|
||||
Nil = 0,
|
||||
/// The "nil" (all zeros) UUID.
|
||||
Nil = 0u8,
|
||||
/// Version 1: Timestamp and node ID.
|
||||
Mac,
|
||||
/// Version 2: DCE Security.
|
||||
@ -302,6 +308,8 @@ pub enum Version {
|
||||
SortRand,
|
||||
/// Version 8: Custom.
|
||||
Custom,
|
||||
/// The "max" (all ones) UUID.
|
||||
Max = 0xff,
|
||||
}
|
||||
|
||||
/// The reserved variants of UUIDs.
|
||||
@ -311,9 +319,10 @@ pub enum Version {
|
||||
/// * [Variant in RFC4122](http://tools.ietf.org/html/rfc4122#section-4.1.1)
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
#[non_exhaustive]
|
||||
#[repr(u8)]
|
||||
pub enum Variant {
|
||||
/// Reserved by the NCS for backward compatibility.
|
||||
NCS = 0,
|
||||
NCS = 0u8,
|
||||
/// As described in the RFC4122 Specification (default).
|
||||
RFC4122,
|
||||
/// Reserved by Microsoft for backward compatibility.
|
||||
@ -545,6 +554,7 @@ impl Uuid {
|
||||
6 => Some(Version::SortMac),
|
||||
7 => Some(Version::SortRand),
|
||||
8 => Some(Version::Custom),
|
||||
0xf => Some(Version::Max),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -835,9 +845,14 @@ impl Uuid {
|
||||
]
|
||||
}
|
||||
|
||||
/// Tests if the UUID is nil.
|
||||
/// Tests if the UUID is nil (all zeros).
|
||||
pub const fn is_nil(&self) -> bool {
|
||||
self.as_u128() == 0
|
||||
self.as_u128() == u128::MIN
|
||||
}
|
||||
|
||||
/// Tests if the UUID is max (all ones).
|
||||
pub const fn is_max(&self) -> bool {
|
||||
self.as_u128() == u128::MAX
|
||||
}
|
||||
|
||||
/// A buffer that can be used for `encode_...` calls, that is
|
||||
@ -1062,19 +1077,41 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
|
||||
fn test_nil() {
|
||||
let nil = Uuid::nil();
|
||||
let not_nil = new();
|
||||
fn test_non_conforming() {
|
||||
let from_bytes =
|
||||
Uuid::from_bytes([4, 54, 67, 12, 43, 2, 2, 76, 32, 50, 87, 5, 1, 33, 43, 87]);
|
||||
|
||||
assert_eq!(from_bytes.get_version(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
|
||||
fn test_nil() {
|
||||
let nil = Uuid::nil();
|
||||
let not_nil = new();
|
||||
|
||||
assert!(nil.is_nil());
|
||||
assert!(!not_nil.is_nil());
|
||||
|
||||
assert_eq!(nil.get_version(), Some(Version::Nil));
|
||||
assert_eq!(not_nil.get_version(), Some(Version::Random))
|
||||
assert_eq!(not_nil.get_version(), Some(Version::Random));
|
||||
|
||||
assert_eq!(nil, Builder::from_bytes([0; 16]).with_version(Version::Nil).into_uuid());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
|
||||
fn test_max() {
|
||||
let max = Uuid::max();
|
||||
let not_max = new();
|
||||
|
||||
assert!(max.is_max());
|
||||
assert!(!not_max.is_max());
|
||||
|
||||
assert_eq!(max.get_version(), Some(Version::Max));
|
||||
assert_eq!(not_max.get_version(), Some(Version::Random));
|
||||
|
||||
assert_eq!(max, Builder::from_bytes([0xff; 16]).with_version(Version::Max).into_uuid());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
24
src/v1.rs
24
src/v1.rs
@ -8,12 +8,15 @@ use crate::{Builder, Timestamp, Uuid};
|
||||
pub use crate::timestamp::context::Context;
|
||||
|
||||
impl Uuid {
|
||||
/// Create a new version 1 UUID using the current system time and a node id.
|
||||
/// Create a new version 1 UUID using the current system time and node ID.
|
||||
///
|
||||
/// This method is only available if both the `std` and `rng` features are enabled.
|
||||
///
|
||||
/// This method is a convenient alternative to [`Uuid::new_v1`] that uses the current system time
|
||||
/// as the source timestamp.
|
||||
///
|
||||
/// Note that usage of this method requires the `v1`, `std`, and `rng` features of this crate
|
||||
/// to be enabled.
|
||||
#[cfg(all(feature = "std", feature = "rng"))]
|
||||
pub fn now_v1(node_id: &[u8; 6]) -> Self {
|
||||
let ts = Timestamp::now(crate::timestamp::context::shared_context());
|
||||
@ -21,13 +24,16 @@ impl Uuid {
|
||||
Self::new_v1(ts, node_id)
|
||||
}
|
||||
|
||||
/// Create a new version 1 UUID using the given timestamp and node id.
|
||||
/// Create a new version 1 UUID using the given timestamp and node ID.
|
||||
///
|
||||
/// Also see [`Uuid::now_v1`] for a convenient way to generate version 1
|
||||
/// UUIDs using the current system time.
|
||||
///
|
||||
/// When generating [`Timestamp`]s using a [`ClockSequence`], this function
|
||||
/// is only guaranteed to produce unique values if the following conditions
|
||||
/// hold:
|
||||
///
|
||||
/// 1. The *node id* is unique for this process,
|
||||
/// 1. The *node ID* is unique for this process,
|
||||
/// 2. The *context* is shared across all threads which are generating version 1
|
||||
/// UUIDs,
|
||||
/// 3. The [`ClockSequence`] implementation reliably returns unique
|
||||
@ -126,6 +132,18 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
|
||||
#[cfg(all(feature = "std", feature = "rng"))]
|
||||
fn test_now() {
|
||||
let node = [1, 2, 3, 4, 5, 6];
|
||||
|
||||
let uuid = Uuid::now_v1(&node);
|
||||
|
||||
assert_eq!(uuid.get_version(), Some(Version::Mac));
|
||||
assert_eq!(uuid.get_variant(), Variant::RFC4122);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
|
||||
fn test_new_context() {
|
||||
|
34
src/v6.rs
34
src/v6.rs
@ -6,12 +6,15 @@
|
||||
use crate::{Builder, Timestamp, Uuid};
|
||||
|
||||
impl Uuid {
|
||||
/// Create a new version 6 UUID using the current time value and a node id.
|
||||
/// Create a new version 6 UUID using the current system time and node ID.
|
||||
///
|
||||
/// This method is only available if the `std` feature is enabled.
|
||||
///
|
||||
/// This method is a convenient alternative to [`Uuid::new_v6`] that uses the current system time
|
||||
/// as the source timestamp.
|
||||
///
|
||||
/// Note that usage of this method requires the `v6`, `std`, and `rng` features of this crate
|
||||
/// to be enabled.
|
||||
#[cfg(all(feature = "std", feature = "rng"))]
|
||||
pub fn now_v6(node_id: &[u8; 6]) -> Self {
|
||||
let ts = Timestamp::now(crate::timestamp::context::shared_context());
|
||||
@ -19,16 +22,19 @@ impl Uuid {
|
||||
Self::new_v6(ts, node_id)
|
||||
}
|
||||
|
||||
/// Create a new version 6 UUID using a time value + sequence +
|
||||
/// *NodeId*.
|
||||
/// This is similar to UUIDv1, except that it is lexicographically sortable by timestamp.
|
||||
/// Create a new version 6 UUID using the given timestamp and a node ID.
|
||||
///
|
||||
/// This is similar to version 1 UUIDs, except that it is lexicographically sortable by timestamp.
|
||||
///
|
||||
/// Also see [`Uuid::now_v6`] for a convenient way to generate version 6
|
||||
/// UUIDs using the current system time.
|
||||
///
|
||||
/// When generating [`Timestamp`]s using a [`ClockSequence`], this function
|
||||
/// is only guaranteed to produce unique values if the following conditions
|
||||
/// hold:
|
||||
///
|
||||
/// 1. The *NodeId* is unique for this process,
|
||||
/// 2. The *Context* is shared across all threads which are generating v1
|
||||
/// 1. The *node ID* is unique for this process,
|
||||
/// 2. The *context* is shared across all threads which are generating version 6
|
||||
/// UUIDs,
|
||||
/// 3. The [`ClockSequence`] implementation reliably returns unique
|
||||
/// clock sequences (this crate provides [`Context`] for this
|
||||
@ -101,7 +107,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
|
||||
fn test_new_v6() {
|
||||
fn test_new() {
|
||||
let time: u64 = 1_496_854_535;
|
||||
let time_fraction: u32 = 812_946_000;
|
||||
let node = [1, 2, 3, 4, 5, 6];
|
||||
@ -131,7 +137,19 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
|
||||
fn test_new_v6_context() {
|
||||
#[cfg(all(feature = "std", feature = "rng"))]
|
||||
fn test_now() {
|
||||
let node = [1, 2, 3, 4, 5, 6];
|
||||
|
||||
let uuid = Uuid::now_v6(&node);
|
||||
|
||||
assert_eq!(uuid.get_version(), Some(Version::SortMac));
|
||||
assert_eq!(uuid.get_variant(), Variant::RFC4122);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
|
||||
fn test_new_context() {
|
||||
let time: u64 = 1_496_854_535;
|
||||
let time_fraction: u32 = 812_946_000;
|
||||
let node = [1, 2, 3, 4, 5, 6];
|
||||
|
@ -3,8 +3,7 @@
|
||||
//! Note that you need to enable the `v7` Cargo feature
|
||||
//! in order to use this module.
|
||||
|
||||
use crate::{rng, timestamp::Timestamp, Builder, Uuid};
|
||||
use core::convert::TryInto;
|
||||
use crate::{std::convert::TryInto, rng, timestamp::Timestamp, Builder, Uuid};
|
||||
|
||||
impl Uuid {
|
||||
/// Create a new version 7 UUID using the current time value and random bytes.
|
||||
@ -63,7 +62,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
|
||||
fn test_new_v7() {
|
||||
fn test_new() {
|
||||
let ts: u64 = 1645557742000;
|
||||
|
||||
let seconds = ts / 1000;
|
||||
@ -85,7 +84,7 @@ mod tests {
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
|
||||
#[cfg(feature = "std")]
|
||||
fn test_now_v7() {
|
||||
fn test_now() {
|
||||
let uuid = Uuid::now_v7();
|
||||
|
||||
assert_eq!(uuid.get_version(), Some(Version::SortRand));
|
||||
@ -94,7 +93,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
|
||||
fn test_new_v7_timestamp_roundtrip() {
|
||||
fn test_new_timestamp_roundtrip() {
|
||||
let time: u64 = 1_496_854_535;
|
||||
let time_fraction: u32 = 812_000_000;
|
||||
|
||||
|
11
src/v8.rs
11
src/v8.rs
@ -1,12 +1,15 @@
|
||||
use crate::{Builder, Uuid};
|
||||
|
||||
impl Uuid {
|
||||
/// Creates a custom UUID comprised almost entirely of user-supplied bytes
|
||||
/// Creates a custom UUID comprised almost entirely of user-supplied bytes.
|
||||
///
|
||||
/// This will inject the UUID Version at 4 bits starting at the 48th bit
|
||||
/// and the Variant into 2 bits 64th bit.
|
||||
/// So if there are bits are supplied in the input buffer, they will not be
|
||||
/// visible in the result
|
||||
/// and the Variant into 2 bits 64th bit. Any existing bits in the user-supplied bytes
|
||||
/// at those locations will be overridden.
|
||||
///
|
||||
/// Note that usage of this method requires the `v8` feature of this crate
|
||||
/// to be enabled.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
|
Loading…
x
Reference in New Issue
Block a user