readable-code-core
Language-agnostic core for readable-code share-code generators: a small chainable string composer plus numeric and random helpers.
This is the shared foundation. For end-user generators, use readable-code-english or readable-code-korean.
Install
Usage
use ;
let out = code.add.dash.digits.build;
// "abc-4821"
build() is the finalizer. It joins the accumulated fragments and returns the code string.
Builder
CodeBuilder is a chainable string composer. Methods take and return self:
add(value)— append an arbitrary string fragment.dash()— append-.digits(length)— appendlengthrandom decimal digits.nums(length)— alias fordigits.add_with(|rng| ...)— append a fragment built from the builder's own random source (language crates use this to add generated words without owning a second source).build()— finalize and return the joinedString.
Random sources
RandomSource is a trait yielding bounded integers in 0..max_exclusive:
Two implementations ship:
OsRandom— cryptographically secure, backed by the OS CSPRNG viagetrandom. This is the default behind the language crates'word()/hangul()entry points, mirroring the TypeScriptcrypto.getRandomValuesdefault.SplitMix64— fast, seeded, reproducible but not cryptographically secure. Use it for deterministic generation in tests/demos (SplitMix64::new(seed)orSplitMix64::from_entropy()), and pass it throughword_with/hangul_with.
Both use rejection sampling to remove modulo bias. Implement RandomSource yourself for custom test doubles.
Helpers
use ;
let mut rng = new;
digits; // "3396" — random decimal digits
pick; // one element (panics on empty slice)
Concept
These are readable public share codes, not secret tokens. Uniqueness is kept separate from the readable part — store generated codes under a database UNIQUE constraint and retry on collision. The builder only composes string fragments; uniqueness, retry, persistence, and denylist policy live outside it.
License
MIT