rust-petname

Generate human-readable random names like remarkably-striking-cricket, as a Rust library or CLI, with built-in English, Turkish, and Luxembourgish word lists.

Library
Cargo
v3.2.0
87stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
66/100Good
Development Activity88
Maintenance72
Community32
Maturity60
Momentum12

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
80/100Excellent
Architecture85
Code Quality90
Innovation78
Learning Curve65

rust-petname is a Rust reimplementation of Dustin Kirkland’s petname project: it builds memorable, easy-to-say names for resources you’d otherwise have to label with sequential IDs or UUIDs — servers, containers, test fixtures, hire bicycles, anything that benefits from a name a human can recall and repeat over a phone call without transcription errors.

The crate is both a library and a command-line tool. As a library it centers on a small, object-safe Generator trait implemented by Petnames (word-list-backed generation) and Alliterations (names where every word shares an initial letter, like proper-pony), both produced via a Namer that exposes either a buffer-reusing generate_into call or a standard Rust Iterator. It is no_std compatible, so it can run in constrained environments like WebAssembly given an external source of randomness.

Word lists ship for English, Turkish, and Luxembourgish, each modeled as its own generator rather than forced through a shared abstraction — Turkish adds emphatic reduplication of adjectives, Luxembourgish adds grammatical gender agreement and the Eifeler Regel sandhi rule at word joins. Custom word lists can be embedded at compile time via the petnames!/english! proc macros, or supplied at runtime.

The petname binary is close to drop-in compatible with the original shell-script petname tool, but runs orders of magnitude faster, with a --count flag capable of streaming millions of names per second and shell-completion generation for bash, zsh, fish, elvish, and PowerShell.

What You Get

  • A Generator trait implemented by Petnames (word-list-backed) and Alliterations (same-initial-letter names), usable as trait objects
  • A Namer with both an allocation-free generate_into(&mut String, ...) call and a standard Iterator for streaming names
  • Three built-in word-list sizes (small/medium/large) for English, plus dedicated Turkish and Luxembourgish generators with real grammar rules (emphatic reduplication, gender agreement, sandhi)
  • The petnames!/english! proc macros to embed your own word lists at compile time, or load lists at runtime instead
  • A petname CLI binary — largely drop-in compatible with the original shell-script petname tool, but with a --count/--stream mode that generates millions of names per second, plus shell-completion generation
  • no_std support (with extern crate alloc) so the generator can run in constrained environments like Wasm

Common Use Cases

  • Naming ephemeral cloud resources — servers, containers, VMs — with something easier to say aloud than a hex ID
  • Generating friendly default names for test fixtures, demo data, or sandboxed accounts
  • Building CLI tools or scripts that need bulk unique-ish names fast (millions per second via --count)
  • Producing alliterative or themed names (e.g. all starting with the same letter) for playful product features
  • Adding non-English (Turkish, Luxembourgish) name generation to a Rust project without hand-rolling grammar rules

Under The Hood

Architecture The library centers on one object-safe trait, Generator, with a single required method generate_into(&self, buf, rng, words, separator). Petnames<'a> (in src/lang/english.rs, re-exported at the crate root) holds three Cow<[&str]> word lists — adjectives, adverbs, nouns — and a private Lists iterator (src/lib.rs) sequences which list to draw from for a requested word count (adverbs first, then one adjective, then a noun). Alliterations<'a> wraps a BTreeMap<char, Petnames<'a>> built by grouping every word by first letter via From<Petnames>, so a generated name naturally alliterates without extra runtime filtering. Both types are driven through a shared Namer<'a, G> config struct (word count + separator + generator reference) that exposes either generate_into for buffer reuse or iter for a standard Rust Iterator built on core::iter::from_fn. This keeps the hot path allocation-light: one String per name via iter, or zero extra allocations if the caller reuses a buffer directly.

Tech Stack A no_std crate (extern crate alloc) depending on rand 0.10 (default-features off, thread_rng opt-in via a default-rng feature) for randomness, with the CLI binary layered on clap 4 (cargo, derive features) and clap_complete for shell completions — both gated behind a clap feature so the library itself pulls in neither. A companion petname-macros proc-macro crate (workspace member) implements the english!/turkish!/luxembourgish!/petnames! macros that read word-list files at compile time and embed them as static arrays; syn/quote-style proc-macro parsing lives in its input.rs, paths.rs, and text.rs. The release profile is tuned for small binaries (lto = true, opt-level = "z", strip = true), and docs.rs metadata builds with --all-features plus --cfg docsrs so feature-gated items get labeled in generated docs.

Code Quality Extensive test coverage across tests/petname.rs, tests/petnames.rs, tests/alliterations.rs, tests/macros.rs, and tests/integration.rs, plus a large body of runnable doctests embedded directly in src/lib.rs’s rustdoc comments — CI runs both cargo hack --workspace --feature-powerset build and test, meaning every combination of feature flags is exercised, not just the defaults. CI additionally enforces cargo fmt --check, cargo clippy -- -D warnings (warnings treated as errors), and a cargo doc build that fails on warnings. unwrap()/expect() usage is confined to test helper code, not library logic. The crate carries an AGENTS.md file documenting its own architecture and conventions for future contributors, including an explicit rationale for why each language generator is a hand-duplicated type rather than a shared abstraction.

What Makes It Unique Most random-name generators stop at English word-list concatenation; this one treats non-English languages as first-class grammar problems rather than word-list swaps. The Turkish generator models emphatic reduplication of adjectives (a real Turkish morphological feature), and the Luxembourgish generator tracks grammatical gender per noun, agrees adjective endings across three forms, and applies a phonological sandhi rule (the Eifeler Regel, dropping a final -n before most consonants) at the join between words — verified by a unit test that lints the built-in word-list data itself, so a bad curation entry fails CI rather than shipping silently. Combined with the deliberate choice to keep the library no_std and allocate minimally via generate_into, it’s built for embedding in latency- or size-sensitive contexts, not just as a developer-convenience CLI.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search