readable-code-core 0.1.1

Core builder, separators, and random helpers for readable share codes.
Documentation
# readable-code-core

Language-agnostic core for [readable-code](https://github.com/semanticist21/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`](https://crates.io/crates/readable-code-english) or [`readable-code-korean`](https://crates.io/crates/readable-code-korean).

## Install

```sh
cargo add readable-code-core
```

## Usage

```rust
use readable_code_core::{code, OsRandom};

let out = code(OsRandom::new()).add("abc").dash().digits(4).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)` — append `length` random decimal digits.
- `nums(length)` — alias for `digits`.
- `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 joined `String`.

## Random sources

`RandomSource` is a trait yielding bounded integers in `0..max_exclusive`:

```rust
pub trait RandomSource {
    fn gen_below(&mut self, max_exclusive: u32) -> u32;
}
```

Two implementations ship:

- **`OsRandom`** — cryptographically secure, backed by the OS CSPRNG via `getrandom`. This is the default behind the language crates' `word()` / `hangul()` entry points, mirroring the TypeScript `crypto.getRandomValues` default.
- **`SplitMix64`** — fast, seeded, **reproducible but not cryptographically secure**. Use it for deterministic generation in tests/demos (`SplitMix64::new(seed)` or `SplitMix64::from_entropy()`), and pass it through `word_with` / `hangul_with`.

Both use rejection sampling to remove modulo bias. Implement `RandomSource` yourself for custom test doubles.

## Helpers

```rust
use readable_code_core::{digits, pick, SplitMix64};

let mut rng = SplitMix64::new(1);
digits(4, &mut rng);                  // "3396" — random decimal digits
pick(&["a", "b", "c"], &mut rng);     // 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