std/identifier/uuid

std/identifier/src/uuid.trb

Uuid: a UUID after RFC 9562, versions 4 and 7, and the urn:uuid: bridge to std/uri (docs/design/URI.md section 12).

type Uuid

type Uuid with Identifier

A UUID per RFC 9562: sixteen bytes, shown as the canonical thirty-six lower-case characters (f81d4fae-7dec-11d0-a765-00a0c91e6bf6). Generated with Uuid.version7, which is the default to reach for: its first 48 bits are the milliseconds since 1970, so a UUID made later compares greater and a database index stays dense. Uuid.version4 is the 122 random bits and nothing else.

Randomness and the clock are arguments, never read: std/identifier has no capability, and a call with a seeded Random is reproducible. The layout of the bits is fixed like Random's, so a seeded source makes the same UUID on every toolchain: see Uuid.version4 and Uuid.version7.

==, hash() and compare() are over the sixteen bytes, and a Uuid is a Map key. Its one conversion pair is String: Uuid.tryFrom reads upper and lower case and String.from(uuid) is the canonical text. A Urn of urn:uuid: is the other way in, and Uri.from(uuid) the other way out.

Examples

var source = Random.seeded 42
const identifier = Uuid.version4 source
print identifier.version()
// prints 4
print Uuid.tryFrom("f81d4fae-7dec-11d0-a765-00a0c91e6bf6")
// prints Ok(f81d4fae-7dec-11d0-a765-00a0c91e6bf6)

Related

  • Ulid - the same sixteen bytes in Crockford base 32.

fn version

fn version(): Int

The version nibble: 4 for a random one, 7 for a time-ordered one, whatever a text of another version says.

fn version4

static fn version4(var source: Random): Self

A version 4: 122 random bits out of source. The layout is frozen: two uint64() draws, the first in bytes 0 to 7 and the second in bytes 8 to 15, each most significant byte first, then the version nibble of byte 6 is set to 4 and the two top bits of byte 8 to 10.

Examples

var source = Random.seeded 0
const made = Uuid.version4 source
print made
// prints e220a839-7b1d-4daf-ae78-9e6aa1b965f4

fn version7

static fn version7(var source: Random, at: Timestamp): Self

A version 7: the 48 bits of at in milliseconds since 1970 (whole milliseconds, the rest of the nanoseconds is cut off), then 74 bits out of source. The layout is frozen: the milliseconds are bytes 0 to 5, most significant first; two uint64() draws follow, the top 12 bits of the first are rand_a (after the version nibble 7) and the top 62 bits of the second are rand_b (after the variant bits 10).

The clock is an argument: Uuid.version7(source, at: Clock.timestamp()) with the clock capability, or a Timestamp the caller was handed.

Examples

var source = Random.seeded 0
const first = Uuid.version7 source, at: Timestamp.fromUnixNanoseconds(0)
print first
// prints 00000000-0000-7e22-9b9e-279aa86e597d

Panics

Where at is before 1970-01-01: the millisecond field is unsigned.

fn bytes

fn bytes(): List<UInt8>

The sixteen bytes, most significant first.

fn show

fn show(): String

The canonical text: thirty-six lower-case characters, dashes after the 4th, 6th, 8th and 10th byte.

fn compare

fn compare(other: Self): Ordering

In the order of the bytes, most significant first: a version 7 of a later millisecond is greater.

extend Uuid with TryFrom<String, IdentifierError>

extend Uuid with TryFrom<String, IdentifierError>

The thirty-six characters of a UUID of either case: eight, four, four, four and twelve hexadecimal digits separated by dashes. The version and the variant are not checked: RFC 9562 text of any version, and the nil and max UUIDs, are read.

Errors

  • IdentifierError with expected a UUID for a wrong length, a misplaced dash or a character that is no hexadecimal digit.

fn tryFrom

static fn tryFrom(text: String): Result<Self, IdentifierError>

extend String with From<Uuid>

extend String with From<Uuid>

The canonical text of a UUID.

fn from

static fn from(value: Uuid): Self

extend Uri with From<Uuid>

extend Uri with From<Uuid>

urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6, the URN namespace of RFC 9562 section 4: the bridge of Uuid to std/uri, which has no dependency on this package.

Examples

const identifier = Uuid.tryFrom("f81d4fae-7dec-11d0-a765-00a0c91e6bf6").expect("a UUID")
const uri = Uri.from identifier
print uri
// prints urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6

fn from

static fn from(value: Uuid): Self

extend Uuid with TryFrom<Urn, IdentifierError>

extend Uuid with TryFrom<Urn, IdentifierError>

A urn:uuid: URN read as a UUID. The namespace identifier is uuid in any case (RFC 8141 makes it case insensitive and Urn has lowered it), the namespace-specific string is the thirty-six characters of a UUID of either case, and the r-, q- and f-components, which RFC 8141 leaves out of a name's identity, are ignored.

Errors

  • IdentifierError with expected a UUID for any other namespace and for a specific string that is no UUID, naming the URN.

fn tryFrom

static fn tryFrom(value: Urn): Result<Self, IdentifierError>