#ulid #unique-identifier #unique #identifier #lexicographical #debugging

mr-ulid

Robust and Hassle-Free ULIDs (Universally Unique Lexicographically Sortable Identifier)

3 stable releases

new 1.1.0 Nov 2, 2024
1.0.1 Oct 31, 2024
1.0.0 Oct 29, 2024

#358 in Encoding

Download history 285/week @ 2024-10-27

292 downloads per month

MIT license

73KB
991 lines

mr-ulid

Crates.io Dependencies License Documentation

Robust and Hassle-Free ULIDs (Universally Unique Lexicographically Sortable Identifiers)

mr-ulid is designed with a focus on correctness and ease of use. It ensures that ULIDs generated are unique and strictly monotonically increasing. By providing both Ulid and ZeroableUlid types, it serves different application needs, whether you require non-zero guarantees or need to handle zero ULIDs.

Key Features

  • Robust: Generates ULIDs that are unique and strictly monotonically increasing under all circumstances, including threads, no failing, and no overflowing random part. See below for Details.
  • Hassle-Free: Simple API for easy usage. Customize entropy source when needed.
  • Non-Zero ULIDs: Provides both non-zero (Ulid) and zeroable (ZeroableUlid) types to suit different use cases.
  • Minimal Dependencies: Actually no dependencies required, only rand enabled by default as Rust lacks a built-in random number generator.
  • Optional Features: Supports serde for serialization and deserialization.

Guarantees

A notable feature of this crate is the guarantee that a sufficient number of ULIDs can be generated at any time without failing or the random part overflowing.

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.

Installation

Add mr-ulid to your Cargo.toml:

[dependencies]
mr-ulid = "1"

By default, the rand feature is enabled.

Quickstart

use mr_ulid::Ulid;

fn main() {
    // Generate a ULID
    let u = Ulid::generate();

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

    // Convert a ULID to a string
    let s = ulid.to_string();

    // Parse the string back into a ULID
    let parsed: Ulid = s.parse().unwrap();

    // Verify that the original and parsed ULIDs are the same
    assert_eq!(u, parsed);
}

Serialization and Deserialization (JSON)

To enable serialization and deserialization, add serde and serde_json to your Cargo.toml, and enable the serde feature for mr-ulid:

[dependencies]
serde = { version = "1", features = ["derive"] }
serde_json = { version = "1" }
mr-ulid = { version = "1", features = ["serde"] }

Example with Serde

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

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

fn main() {
    let example = Example {
        id: Ulid::generate(),
        data: "Hello, ULID!".to_string(),
    };

    // Serialize to JSON
    let json = serde_json::to_string(&example).unwrap();
    println!("Serialized JSON: {json}");

    // Deserialize back to struct
    let deserialized: Example = serde_json::from_str(&json).unwrap();

    // Verify that the original and deserialized structs are the same
    assert_eq!(example, deserialized);
}

Contributing

Contributions are welcome! Whether it's a bug fix, new feature, or improvement, your help is appreciated. Please feel free to open issues or submit pull requests on the GitHub repository.

License

This project is licensed under the MIT License.

Dependencies

~290–690KB
~13K SLoC