Skip to main content

Crate mr_ulid

Crate mr_ulid 

Source
Expand description

§Robust and Hassle-Free ULIDs

This crate provides an implementation of ULIDs (Universally Unique Lexicographically Sortable Identifiers) with an emphasis on correctness, resilience, and hassle-free usability, in that order. It enables the generation and manipulation of ULIDs that are guaranteed to be unique and strictly monotonically increasing in any circumstances.

§Generating ULIDs

ULIDs are generated using the Ulid::new() method:

use mr_ulid::Ulid;

let u = Ulid::new();

Each ULID generated is guaranteed to be unique and strictly monotonically increasing. The generation is thread-safe, maintaining all guarantees even when ULIDs are produced concurrently across multiple threads.

§Printing ULIDs and converting to Strings

ULIDs implement the std::fmt::Display trait:

use mr_ulid::Ulid;

let u = Ulid::new();

println!("Generated ULID: {u}");

let s = u.to_string();

§Parsing ULIDs from Strings:

ULIDs implements the std::str::FromStr trait and can be parsed with str::parse() method:

use mr_ulid::Ulid;

// Method A
let u1: Ulid = "01JB5C84ZBM8QVBE5QRZW6HY89".parse()?;

// Method B
let u2 = "01JB5C84ZBM8QVBE5QRZW6HY89".parse::<Ulid>()?;

§Serializing and Deserializing using Serde (JSON)

For serializing/deserializing the feature flag serde needs to be enabled:

cargo add mr-ulid -F serde

Once the serde feature is enabled, ULIDs implement the Serialize and Deserialize traits:

use mr_ulid::Ulid;
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct Example {
    id: Ulid,
    data: String,
}

let e1 = Example {
    id: Ulid::new(),
    data: "Hello, World!".to_string(),
};

let s = serde_json::to_string(&e1)?;

println!("JSON: {s}");

let e2: Example = serde_json::from_str(&s)?;

assert_eq!(e1, e2);

§Guarantees

A notable feature of this crate is the guarantee that a sufficient number of ULIDs can be generated at any time without the random part overflowing and the guarantees of uniqueness and strict monotonicity is maintained under all circumstances.

The 80-bit random component of a ULID is slightly reduced by 1010 values, resulting in a negligible reduction in entropy of approximately 0.000000000001%. This ensures that at least 1010 ULIDs can be generated per millisecond, equating to 1013 ULIDs per second. Such capacity exceeds the capabilities of current systems by magnitudes.

In the very unlikely event that a system could generate more than 1013 ULIDs per second, any overflowing random part is projected into the next millisecond. There, the full range of 280 (ca. 1024) is available.

§ULID Types

  • Ulid: This is the preferred type for most use cases and represents a ULID that can never be zero.
  • ZeroableUlid: This alternative type allows for zero values ULIDs (e.g., "00000000000000000000000000").

In idiomatic Rust code, if an absent ULID is needed, it is best represented as Option<Ulid>. However, for use cases that may represent absent ULIDs with a zero ULID, the ZeroableUlid may be an easier choice.

§Feature Flags

  • rand: Utilizes the rand crate as the source for random numbers, enabled by default.
  • serde: Provides support for serialization and deserialization via Serde, optional.

Structs§

EntropySourceHandle
An opaque handle for entropy sources.
Ulid
A ULID which never is zero.
ZeroableUlid
A ULID with even the value zero allowed.

Enums§

Error
Errors that can occur when creating ULIDs out of foreign data.

Constants§

NO_ENTROPY_SOURCE
No-Operation entropy source.
STANDARD_ENTROPY_SOURCE
Standard entropy source.

Traits§

EntropySource
Trait for entropy sources.

Functions§

canonicalize
Canonicalizes a ULID string by converting it to a standard format.
set_entropy_source
Sets the entropy source for generating ULIDs.
validate
Checks a ULID string for validity.