MCPcopy Index your code
hub / github.com/allenap/rust-petname

github.com/allenap/rust-petname @v3.1.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v3.1.0 ↗ · + Follow
129 symbols 226 edges 18 files 26 documented · 20% updated 10d agov3.1.0 · 2026-06-28★ 843 open issues
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

rust-petname

Generate human readable random names.

🚨 Upgrading?

Check the notes on switching from 2.x to 3.x and from 1.x to 2.x.

Petnames are useful when you need to name a large number of resources – like servers, services, perhaps bicycles for hire – and you want those names to be easy to recall and communicate unambiguously. For example, over a telephone compare saying "please restart remarkably-striking-cricket" with "please restart s01O97i4": the former is easier to say and less likely to be misunderstood. Avoiding sequential names adds confidence too: petnames have a greater lexical distance between them, so errors in transcription can be more readily detected.

This crate is both a command-line tool and a Rust library. Dustin Kirkland's petname project is the inspiration for this project. The word lists and the basic command-line UX here are taken from there. Check it out! Dustin maintains packages for Python, and Golang too.

Notable features:

  • Choose from 3 built-in word lists, or provide your own.
  • english! (aliased as petnames!) and turkish! (with feature lang-turkish) macros to statically embed word lists at compile-time.
  • Alliterative names, like viable-vulture, proper-pony, ...
  • Build names with 1-255 components (adjectives, adverbs, nouns).
  • Name components can be unseparated, or joined by any character or string.
  • Generate 1..n names, or stream names continuously.
  • no_std support (see later section).
  • Compile without built-in dictionaries to reduce library/binary size.

Command-line utility

If you have [installed Cargo][install-cargo], you can install rust-petname with cargo install petname. This puts a petname binary in ~/.cargo/bin, which the Cargo installation process will probably have added to your PATH.

🍺 Homebrew – You can instead install it from the allenap/utils tap. The formula is named rust-petname and provides the same petname command:

shellsession $ brew install allenap/utils/rust-petname

The petname binary from rust-petname is mostly drop-in compatible with the original petname. It has more options and it's stricter when validating arguments, but for most uses it should behave the same[^differences].

[^differences]: When using the --dir option, Dustin Kirkland's petname looks for a file named names.txt whereas this looks for nouns.txt first before checking for names.txt.

$ petname -h
Generate human readable random names

Usage: petname [OPTIONS] [COMMAND]

Commands:
  completions  Print a shell completion script to standard output
  help         Print this message or the help of the given subcommand(s)

Options:
  -w, --words <WORDS>             Number of words in name [default: 2]
  -s, --separator <SEP>           Separator between words [default: -]
      --language <LANG>           Language to generate names in [default: english] [aliases: --lang] [possible values: english, turkish]
      --lists <LIST>              Use the built-in word lists with small, medium, or large words [default: medium] [possible values: small, medium, large]
  -c, --complexity <NUM>          Alias for compatibility with upstream; prefer --lists instead
  -d, --dir <DIR>                 Use custom word lists by specifying a directory containing `adjectives.txt`, `adverbs.txt`, and `nouns.txt`
      --count <COUNT>             Generate multiple names; or use --stream to generate continuously [default: 1]
      --stream                    Stream names continuously
  -l, --letters <LETTERS>         Maximum number of letters in each word; 0 for unlimited [default: 0]
  -a, --alliterate                Generate names where each word begins with the same letter
  -A, --alliterate-with <LETTER>  Generate names where each word begins with the given letter
  -u, --ubuntu                    Alias for compatibility with upstream; prefer --alliterate instead
      --seed <SEED>               Seed the RNG with this value (unsigned 64-bit integer in base-10)
  -h, --help                      Print help (see more with '--help')
  -V, --version                   Print version

Based on Dustin Kirkland's petname project <https://github.com/dustinkirkland/petname>.

$ petname
unified-platypus

$ petname -s _ -w 3
lovely_notable_rooster

Languages

Beyond the default English word lists, rust-petname can generate names in other languages with their own grammar-aware generators. These are gated behind per-language features (so the default build stays small) and selected with --language.

Turkish is available via the lang-turkish feature. It is grammatically simple for this purpose – no gender, no adjective agreement, adjective-before-noun order – and it models Turkish's distinctive emphatic reduplication (pekiştirme), so a two-word name may intensify the adjective morphologically:

$ petname --language turkish --words 2
kıpkırmızı-kedi

$ petname --language turkish --words 3
çok-güzel-yıldız

More languages (Luxembourgish, French, German, …) are planned. Each is a distinct generator, so languages with grammatical gender, agreement, or word-order rules can be modelled properly rather than approximated.

Shell completions

petname completions <SHELL> prints a completion script to standard output, for bash, zsh, fish, elvish, or powershell. Redirect it to the location your shell loads completions from, for example:

$ petname completions zsh > ~/.zfunc/_petname
$ petname completions bash > /etc/bash_completion.d/petname
$ petname completions fish > ~/.config/fish/completions/petname.fish

This is an ordinary subcommand, so petname on its own still generates names as usual. If you installed via Homebrew, the completions are set up for you.

Performance

This implementation is considerably faster than the upstream petname:

$ time /usr/bin/petname
fit-lark

real    0m0.038s
user    0m0.032s
sys     0m0.008s

$ time target/release/petname
contiguous-seriema

real    0m0.004s
user    0m0.001s
sys     0m0.002s

These timings are irrelevant if you only need to name a single thing, but if you need to generate 100s or 1000s of names then rust-petname is handy:

$ time { for i in $(seq 1000); do /usr/bin/petname; done; } > /dev/null

real    0m32.058s
user    0m29.360s
sys     0m5.163s

$ time { for i in $(seq 1000); do target/release/petname; done; } > /dev/null

real    0m2.293s
user    0m1.044s
sys     0m1.003s

To be fair, /usr/bin/petname is a shell script. The Go command-line version (available from the golang-petname package on Ubuntu) is comparable to the Rust version for speed, but has very limited options compared to its shell-script ancestor and to rust-petname.

Lastly, rust-petname has a --count option that speeds up generation of names considerably:

$ time target/release/petname --count=10000000 > /dev/null

real    0m0.785s
user    0m0.767s
sys     0m0.016s

That's ~408,000 (four hundred and eight thousand) times faster, for about 12.7 million petnames a second on this hardware. This is useful if you want to apply an external filter to the names being generated:

$ petname --words=3 --stream | grep 'love.*\bsalmon$'

Library

You can use rust-petname in your own Rust projects with cargo add petname.

Features & no_std support

There are features that can be selected, and many than can be deselected (since they're enabled by default):

  • default-rng enables std and std_rng in rand. A couple of convenience functions depend on this for a default RNG.
  • default-words enables the default word lists. Deselecting this will reduce the size of compiled artifacts.
  • clap enables the clap command-line argument parser, which is needed to build the petname binary.
  • NOTE that clap is not necessary for the library at all, and you can deselect it, but it is presently a default feature since otherwise it's inconvenient to build the binary. This will probably change in the future.
  • macros enables the english! macro (and its petnames! alias). It's required for the default-words feature, but otherwise it can be deselected.
  • lang-turkish (not a default) compiles the Turkish generator and enables --language turkish. Like the English lists, the built-in Turkish word lists are embedded only when default-words is also enabled. See Languages.

All of the default features are required to build the command-line utility.

The library can be built without any default features, and it will work in a no_std environment, like Wasm. You'll need to figure out a source of randomness, but SmallRng::seed_from_u64 may be a good starting point.

Upgrading

From 3.0.0 to 3.0.1

3.0.1 is purely additive – nothing is required to upgrade, and the default build is unchanged. It adds non-English generators (see Languages). The new --language flag (alias --lang) selects the language; the lang-turkish feature compiles a Turkish generator and makes --language turkish available. The word-list macro is now english!, with petnames! kept as a backwards-compatible alias, and a turkish! macro is available when the lang-turkish feature is enabled.

From 2.x to 3.x

Version 3.0 brings a few breaking changes to the API, but the command-line is largely unchanged.

Command-line

  • One subtle change: if you use --seed, the generated names will differ from 2.x, since rand 0.10 produces different output for the same seed.

Library

  • The rand dependency has been bumped from 0.9 to 0.10. If you depend on rand types (e.g. RngCore, SmallRng) directly in your own code, you will need to upgrade your rand dependency to match.
  • The Generator trait has changed significantly:
  • The generate and generate_one methods are gone.
  • The trait no longer has a lifetime parameter; Generator<'a> is now just Generator.
  • The one required method is generate_into.
  • The iter method has been renamed to namer. It now returns a [Namer] directly instead of Box<dyn Iterator<Item = String>>, so there is no heap allocation for the iterator itself.
  • [Namer] is a new public type (an iterator over generated petnames). It is generic over the generator type, so Namer<Petnames> and Namer<Alliterations> are both valid.
  • The built-in word lists are now compiled into the library via the petnames! proc macro rather than via build.rs. This is mostly an internal change, but it does mean that the petname-macros crate is a new compile-time dependency when the default-words or macros features are enabled.
  • A new macros feature flag exposes the petnames! proc macro as public API. It is enabled by default. You can use it to embed custom word lists at compile time: rust let p = petname::petnames!("path/to/my/words");

From 1.x to 2.x

Version 2.0 brought several breaking changes to both the API and the command-line too. Below are the most important:

Command-line

  • The --complexity <COMPLEXITY> option has been replaced by --lists <LISTS>.
  • For compatibility, --complexity [0,1,2] will still work, but its availability is not shown in the -h|--help text.
  • The default is now "medium" (equivalent to --complexity 1). Previously it was "small" (--complexity 0).
  • When using custom word lists with --dir <DIR>, nouns are now found in a file named appropriately DIR/nouns.txt. Previously this was names.txt but this was confusing; the term "names" is overloaded enough already.
  • For compatibility, if nouns.txt is not found, an attempt will be made to load nouns from names.txt.
  • The option --count 0 is no longer a synonym for --stream. Use --stream instead. It's not an error to pass --count 0, but it will result in zero names being generated.
  • The --non-repeating flag is no longer recognised ([#101]).

Library

  • Feature flags have been renamed:
  • std_rng is now default-rng,
  • default_dictionary is now default-words.
  • The names field on the Petnames struct has been renamed to nouns.
  • Petnames::new() is now Petnames::default().
  • Petnames::new(…) now accepts word lists as strings.
  • Names is no longer public. This served as the iterator struct returned by Petnames::iter(…), but this now hides the implementation details by returning impl Iterator<Item = String> instead. This also means that Names::cardinality(&self) is no longer available; use Petnames::cardinality(&self, words: u8) instead.
  • Petnames::iter_non_repeating has been removed ([#101]).
  • Petnames::generate, Petnames::generate_one, and Petnames::iter have been extracted into a Generator trait. This must be in scope in order to call th

Extension points exported contracts — how you extend this code

Core symbols most depended-on inside this repo

Shape

Function 69
Method 43
Class 9
Enum 7
Interface 1

Languages

Rust100%

Modules by API surface

src/main.rs28 symbols
src/lib.rs22 symbols
src/lang/turkish.rs17 symbols
src/cli.rs12 symbols
src/lang/english.rs10 symbols
tests/petnames.rs9 symbols
tests/alliterations.rs6 symbols
tests/mocks.rs5 symbols
petname-macros/src/paths.rs4 symbols
petname-macros/src/text.rs3 symbols
petname-macros/src/lib.rs3 symbols
petname-macros/src/lang/turkish.rs3 symbols

For agents

$ claude mcp add rust-petname \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page