4 stable releases
new 1.1.1 | Nov 22, 2024 |
---|---|
1.1.0 | Nov 2, 2024 |
1.0.1 | Oct 31, 2024 |
1.0.0 | Oct 29, 2024 |
#322 in Encoding
385 downloads per month
72KB
989 lines
mr-ulid
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 non-zero (
Ulid
) and zeroable (ZeroableUlid
) types. - 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 guarantee of this crate is 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"
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–680KB
~12K SLoC