Skip to content

Commit

Permalink
Merge pull request #631 from KodrAus/feat/docs-hash
Browse files Browse the repository at this point in the history
More work on docs
  • Loading branch information
KodrAus committed Oct 6, 2022
2 parents 9fcb760 + 527cd3f commit d626fd5
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 39 deletions.
36 changes: 31 additions & 5 deletions src/builder.rs
Expand Up @@ -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};
Expand All @@ -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);
Expand Down Expand Up @@ -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))
}
Expand Down Expand Up @@ -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,
Expand Down
65 changes: 51 additions & 14 deletions src/lib.rs
Expand Up @@ -85,14 +85,18 @@
//! * `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?
//!
//! If you just want to generate unique identifiers then consider version 4 (`v4`) UUIDs. If you want
//! 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:
Expand Down Expand Up @@ -132,9 +136,10 @@
//!
//! ```toml
//! [dependencies.uuid]
//! version = "1"
//! version = "1.1.2"
//! features = [
//! "v4",
//! "v7",
//! "js",
//! ]
//! ```
Expand All @@ -146,7 +151,7 @@
//!
//! ```toml
//! [dependencies.uuid]
//! version = "1"
//! version = "1.1.2"
//! default-features = false
//! ```
//!
Expand All @@ -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;
Expand All @@ -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.
Expand Down Expand Up @@ -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.
Expand All @@ -302,6 +308,8 @@ pub enum Version {
SortRand,
/// Version 8: Custom.
Custom,
/// The "max" (all ones) UUID.
Max = 0xff,
}

/// The reserved variants of UUIDs.
Expand All @@ -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.
Expand Down Expand Up @@ -545,6 +554,7 @@ impl Uuid {
6 => Some(Version::SortMac),
7 => Some(Version::SortRand),
8 => Some(Version::Custom),
0xf => Some(Version::Max),
_ => None,
}
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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]
Expand Down
24 changes: 21 additions & 3 deletions src/v1.rs
Expand Up @@ -8,26 +8,32 @@ 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());

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
Expand Down Expand Up @@ -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() {
Expand Down
34 changes: 26 additions & 8 deletions src/v6.rs
Expand Up @@ -6,29 +6,35 @@
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());

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
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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];
Expand Down
9 changes: 4 additions & 5 deletions src/v7.rs
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand All @@ -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));
Expand All @@ -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;

Expand Down

0 comments on commit d626fd5

Please sign in to comment.