Expand description
§TNID
Type-checked, Named IDs that are fully compatible with UUIDs.
TNID (“Typed Named ID”, pronounced “tee-nid”) embeds a human-readable name directly into a UUID-compatible 128-bit identifier. Each TNID carries a 1-4 character type name (like “user” or “post”) that’s validated at compile time, preventing you from accidentally mixing up IDs for different entity types.
§Quick Start
use tnid::{Tnid, TnidName, NameStr};
// Define a name type for your entity
struct User;
impl TnidName for User {
const ID_NAME: NameStr<'static> = NameStr::new_const("user");
}
// Generate IDs
let id = Tnid::<User>::new_v0(); // Time-ordered (like UUIDv7)
// Display as a TNID string
println!("{}", id); // e.g., "user.Br2flcNDfF6LYICnT"
// Or as a standard UUID for database storage
let uuid_str = id.to_uuid_string_cased(false);
// e.g., "cab1952a-f09d-86d9-928e-96ea03dc6af3"§Why TNIDs?
TNIDs solve several common problems with plain UUIDs:
- Type Safety:
Tnid<User>andTnid<Post>are different types. You can’t accidentally pass a post ID where a user ID is expected. - Human Readable: The TNID string format (
user.Br2flcNDfF6LYICnT) tells you at a glance what kind of entity the ID refers to. - UUID Compatible: Every TNID is a valid UUIDv8, so it works with existing UUID columns in databases and UUID-based APIs.
§TNID Variants
Like UUID versions, TNIDs come in different variants:
- V0 (
Tnid::new_v0) - Time-ordered with millisecond precision (like UUIDv7). Use when you want IDs to sort chronologically. - V1 (
Tnid::new_v1) - High-entropy random (like UUIDv4). Use when you want maximum randomness without time information.
See TnidVariant for details.
§String Representations
TNIDs support two string formats:
- TNID format (
user.Br2flcNDfF6LYICnT): Human-readable, sortable, unambiguous - UUID format (
cab1952a-f09d-86d9-928e-96ea03dc6af3): Standard UUID hex for compatibility
let id = Tnid::<User>::new_v1();
// TNID string (for APIs, logs, user-facing contexts)
let tnid_str = id.as_tnid_string();
// UUID string (for databases, UUID-based systems)
let uuid_str = id.to_uuid_string_cased(false);
// Parse back
let from_tnid = Tnid::<User>::parse_tnid_string(&tnid_str);
let from_uuid = Tnid::<User>::parse_uuid_string(&uuid_str);§Feature Flags
| Feature | Default | Description |
|---|---|---|
time | ✓ | Enables Tnid::new_v0 with automatic timestamps |
rand | ✓ | Enables Tnid::new_v0 and Tnid::new_v1 with automatic randomness |
encryption | Enables Tnid::encrypt_v0_to_v1 and Tnid::decrypt_v1_to_v0 for hiding timestamps | |
uuid | Integration with the uuid crate |
Without the default features, you can still create TNIDs using explicit components:
Tnid::new_v0_with_parts- Provide your own timestamp and random bitsTnid::new_v1_with_random- Provide your own random bits
§Reliability
This crate is designed to never panic in normal use. All functions that could potentially panic are fuzz tested with randomized inputs to verify they don’t. Extensive unit tests verify correctness of encoding, sorting, and round-trip conversions.
Modules§
- encryption
encryption - TNID encryption utilities.
Structs§
- NameStr
- A validated TNID name string.
- Tnid
- A type-safe TNID parameterized by name.
- UUID
Like - A wrapper for 128-bit values that may or may not be valid TNIDs.
Enums§
- Tnid
Variant - The 4 possible TNID variants.
Traits§
- Tnid
Name - Intended to be used on empty structs to create type checked TNID names.