UUID tools
UUIDs beyond the random uuid(): version 7 sorted by time for database keys, versions 5 and 3 that give the same id for the same name, and any UUID read with its version and time.
Version 1.0.0 · 6 functions · 1 crate
Functions
What use uuid_tools.qwer gives a program, with the types Quillo sees. To take only some, or under other names: use uuid_v7, uuid_v7_at from uuid_tools (Quillo 0.6).
uuid_v7() → strA new version 7 UUID: its first 48 bits are the time in milliseconds, so ids made later sort after (within one server, even in the same millisecond), and database indexes stay compact.
uuid_v7_at(time_ms: int) → stror an errorA version 7 UUID for a time in milliseconds since 1970 (as now() gives), the rest random: for back-filling old rows, or the lowest id of a time range.
uuid_v5(namespace: str, name: str) → stror an errorThe version 5 UUID of name in namespace ("dns", "url", "oid", "x500", or a UUID of your own), by SHA-1: the same name always gives the same id, so an import can find its rows again. uuid_v5("dns", "example.com") is "cfbff0d1-9375-5685-968c-48ce8b15ae17".
uuid_v3(namespace: str, name: str) → stror an errorAs uuid_v5, by MD5 (version 3), for systems that use those.
uuid_parse(text: str) → anyor an errorAny UUID read, in any of its forms (with or without dashes, braces or "urn:uuid:"): { uuid, version, variant, time_ms, simple, urn, nil }. time_ms is when versions 1, 6 and 7 were made (else null); uuid the usual lower-case form. An error when it is not a UUID.
uuid_valid(text: str) → boolWhether text is a UUID in any of its forms.
Get it
$ quillo install uuid_tools # uuid_tools.qwer into this folder$ quillo install uuid_tools --example # and its example, uuid_tools.qweOr with curl:
$ curl -O https://quillolang.org/plugins/files/uuid_tools.qwer$ curl -O https://quillolang.org/plugins/files/uuid_tools.qweThen, in your program, all of it or only what you call:
use uuid_tools.qweruse uuid_v7, uuid_v7_at from uuid_tools // Quillo 0.6: only theseIt uses this crate, which cargo fetches the first time the plugin is built:
uuid = { version = "1", features = ["v3", "v5", "v7", "std"] }Example
// Database keys that sort by time (v7), ids for imported rows that stay the same on every import (v5), and any UUID read back.//// quillo run uuid_tools.qwe then open http://localhost:8080/keysuse "uuid_tools.qwer"route GET /keys { let a = uuid_v7() let b = uuid_v7() { a, b, sorted: a < b, made: uuid_parse(a)?.version, random: uuid_parse(uuid())?.version }}// The same customer email gives the same id on every import.route GET /import = ["ada@example.com", "grace@example.com", "ada@example.com"] | map((e) => { email: e, id: uuid_v5("6ba7b811-9dad-11d1-80b4-00c04fd430c8", e)? })route GET /read ? { id: str = "{CFBFF0D1-9375-5685-968C-48CE8B15AE17}" } = uuid_parse(id)?route GET /known = { dns: uuid_v5("dns", "example.com")?, old: uuid_parse(uuid_v7_at(1767225600000)?)?.time_ms, valid: [uuid_valid("nope"), uuid_valid(uuid())] }$ quillo run uuid_tools.qwe$ curl 'localhost:8080/keys'$ curl 'localhost:8080/known'$ curl 'localhost:8080/read'Source
//! UUIDs beyond Quillo's random `uuid()`: version 7 (sorted by time, a good database key), version 5 and 3 (the same name always gives the same id), and any UUID read: its version, variant and time.//! version: 1.0.0//!//! [dependencies]//! uuid = { version = "1", features = ["v3", "v5", "v7", "std"] }use serde_json::{json, Value};use uuid::{NoContext, Timestamp, Uuid};fn namespace(ns: &str) -> Result<Uuid, String> { Ok(match ns.trim().to_lowercase().as_str() { "dns" => Uuid::NAMESPACE_DNS, "url" => Uuid::NAMESPACE_URL, "oid" => Uuid::NAMESPACE_OID, "x500" => Uuid::NAMESPACE_X500, other => Uuid::parse_str(other).map_err(|_| format!("namespace is \"dns\", \"url\", \"oid\", \"x500\" or a UUID, not {:?}", ns))?, })}/// A new version 7 UUID: its first 48 bits are the time in milliseconds, so ids made later sort after (within one server, even in the same millisecond), and database indexes stay compact.pub fn uuid_v7() -> String { Uuid::now_v7().to_string()}/// A version 7 UUID for a time in milliseconds since 1970 (as `now()` gives), the rest random: for back-filling old rows, or the lowest id of a time range.pub fn uuid_v7_at(time_ms: i64) -> Result<String, String> { if time_ms < 0 { return Err("times from 1970".into()); } Ok(Uuid::new_v7(Timestamp::from_unix(NoContext, (time_ms / 1000) as u64, ((time_ms % 1000) * 1_000_000) as u32)).to_string())}/// The version 5 UUID of `name` in `namespace` ("dns", "url", "oid", "x500", or a UUID of your own), by SHA-1: the same name always gives the same id, so an import can find its rows again. `uuid_v5("dns", "example.com")` is "cfbff0d1-9375-5685-968c-48ce8b15ae17".pub fn uuid_v5(namespace: &str, name: &str) -> Result<String, String> { Ok(Uuid::new_v5(&self::namespace(namespace)?, name.as_bytes()).to_string())}/// As `uuid_v5`, by MD5 (version 3), for systems that use those.pub fn uuid_v3(namespace: &str, name: &str) -> Result<String, String> { Ok(Uuid::new_v3(&self::namespace(namespace)?, name.as_bytes()).to_string())}/// Any UUID read, in any of its forms (with or without dashes, braces or "urn:uuid:"): `{ uuid, version, variant, time_ms, simple, urn, nil }`. `time_ms` is when versions 1, 6 and 7 were made (else null); `uuid` the usual lower-case form. An error when it is not a UUID.pub fn uuid_parse(text: &str) -> Result<Value, String> { let u = Uuid::parse_str(text.trim()).map_err(|e| format!("{:?} is not a UUID: {}", text, e))?; let time_ms = u.get_timestamp().map(|t| { let (s, n) = t.to_unix(); s as i64 * 1000 + (n / 1_000_000) as i64 }); Ok(json!({ "uuid": u.hyphenated().to_string(), "version": u.get_version_num(), "variant": format!("{:?}", u.get_variant()), "time_ms": time_ms, "simple": u.simple().to_string(), "urn": u.urn().to_string(), "nil": u.is_nil(), }))}/// Whether `text` is a UUID in any of its forms.pub fn uuid_valid(text: &str) -> bool { Uuid::parse_str(text.trim()).is_ok()}Related
ksuid.qwer · 1.0.0KSUIDs, Segment's K-Sortable Unique IDs: 27 base62 characters sorted by the second they were made, with 128 random bits; made, read back and checked.8 views · 7 downloadsShort ids short_ids.qwer · 1.0.0Short ids for URLs made from your database's numbers and read back (Sqids): your own alphabet, a minimum length, no rude words, and typos never reaching another row.6 views · 8 downloadsTypeID typeid.qwer · 1.0.0TypeIDs such as user_01h455vb4pex5vsknk084sn02q: a type prefix and a UUIDv7 in base32, made, read back to their UUID and time, and checked against the type a URL expects.6 views · 7 downloadsCUID2 cuid2.qwer · 1.0.0CUID2 ids: secure, collision-resistant, starting with a letter, of the length you choose, that give away neither the time nor a count; and a check that a string is one.7 views · 7 downloadsSnowflake ids snowflake.qwer · 1.0.0Snowflake ids: 64-bit numbers that sort by time, unique across 1,024 servers with no coordination, with their time, server and sequence read back and the first id of a time for range queries.7 views · 7 downloadsULIDs ulid.qwer · 1.0.0Unique ids that sort by when they were made: 26 characters, safe in URLs, good primary keys.8 views · 8 downloadsThread 0 posts
On UUID tools: questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.