Basic operations
Install a library from Libraries; each repository has its own install and API docs. Examples are in Rust and TypeScript; the tabs switch every block on the page.
Define a type per name
Each kind of thing you identify gets one TNID type, with its name fixed in that type. The rest of the guide uses this user type.
use tnid::{NameStr, Tnid, TnidName};
struct User;
impl TnidName for User {
const ID_NAME: NameStr<'static> = NameStr::new_const("user");
}import { Tnid, type TnidType } from "@tnid/core";
const UserId = Tnid("user");
type UserId = TnidType<typeof UserId>;Generate
TNIDv0, the time-sortable kind, sorts by creation time within each name and is the default. When creation time must stay secret from whoever sees the TNID, use TNIDv1, or store TNIDv0 and show it encrypted as TNIDv1.
let user_id = Tnid::<User>::new_v0();
println!("{user_id}"); // user.Br2flcNDfF6LYICnTconst userId: UserId = UserId.new_v0();
console.log(userId); // user.Br2flcNDfF6LYICnTShow and store
Show the TNID string to people and in URLs. Store the UUID form, which is the same 128-bit value.
use tnid::Case;
let uuid = user_id.to_uuid_string(Case::Lower);
println!("{uuid}"); // d6157337-0ebc-8686-83ab-4075a34cdcdeconst uuid = UserId.toUuidString(userId);
console.log(uuid); // d6157337-0ebc-8686-83ab-4075a34cdcdeParse
Parsing accepts either form and checks the name, so a post TNID is rejected where a user TNID is expected.
let from_tnid: Tnid<User> = "user.Br2flcNDfF6LYICnT".parse()?;
let from_uuid: Tnid<User> = "d6157337-0ebc-8686-83ab-4075a34cdcde".parse()?;
let wrong: Result<Tnid<User>, _> = "post.Br2flcNDfF6LYICnT".parse(); // Errconst fromTnid: UserId = UserId.parse("user.Br2flcNDfF6LYICnT");
const fromUuid: UserId = UserId.parse("d6157337-0ebc-8686-83ab-4075a34cdcde");
UserId.parse("post.Br2flcNDfF6LYICnT"); // throws