| Crates.io | swappy |
| lib.rs | swappy |
| version | 2.0.0 |
| created_at | 2020-06-26 18:49:19.970525+00 |
| updated_at | 2025-12-19 22:00:49.944469+00 |
| description | An anagram generator |
| homepage | https://gitlab.com/nathanl/swappy.rs |
| repository | https://gitlab.com/nathanl/swappy.rs |
| max_upload_size | |
| id | 258483 |
| size | 39,764 |
Anagrams are useless but funny. Let's make some!
Swappy efficiently finds anagrams of a given input phrase using a word list file.
cargo install swappy
swappy 'my phrase'WORDLIST=/some/file.txt swappy 'my phrase' --limit 20 swappy 'applesauce' --require 'apple' --require 'us' --exclude 'cause' --exclude 'cue'Suppose you're getting anagrams for "rust anagrams library" and you see "triangular brass army". You like "triangular", but not the rest.
You can try again with 'rust anagrams library' --require 'triangular' to see only anagrams that include 'triangular', and add as --excludes to remove results with words you don't want.
By default, Swappy looks for a word list file at ~/.swappy_wordlist, but you can set the WORDLIST env var to another file.
Swappy's repo contains a wordlist file sorted longest to shortest, and with many short, uncommon words (like "oe" and "mu") removed for increased efficiency.
Swappy prioritizes anagrams containing words that occur earlier in the word list, and lets you limit how many anagrams are produced. This lets you tailor what kinds of results you want (eg, by putting words you think are funny at the top, or sorting the list longest to shortest for impressive finds).
Swappy can also be used as a Rust library. Add it to your Cargo.toml:
[dependencies]
swappy = { path = "." }
Then use the find_anagrams function in your code:
use swappy::{find_anagrams, load_wordlist_from_file};
fn main() -> Result<(), String> {
let word_list = load_wordlist_from_file("~/.swappy_wordlist")?;
let (checked_nodes, anagrams) = find_anagrams("rust", &word_list, 10, None)?;
for anagram in anagrams {
println!("{}", anagram);
}
Ok(())
}
The library exposes:
find_anagrams(phrase, word_list, limit, require) - Find anagrams for a phraseload_wordlist_from_file(path) - Load words from a fileSwappy is efficient, but has more work to do as it's given:
--limit argIf you accept user input for it, control your dictionary and impose sensible limits.
Swappy performs a depth-first search of the tree of possible anagrams which use our word list and phrase. A node where there are no remaining letters is an anagram.
Our tree could look like this, where a node is represented as [found words] / [remaining letters].
racecar /
race / car
race a / cr [failed leaf]race car / [successful leaf]racer / ca
racer a / c [failed leaf]Before deciding if a phrase contains a word, it converts them both to "alphagrams", which are order-agnostic; "bat" and "tab" have the same alphagram. We represent alphagrams internally as a hashmap listing the count of each character. This makes comparison and subtraction efficient.
Swappy is single-threaded, but performs well. I considered a multi-threaded design, but could not think of a good way to use multiple threads and still guarantee that results are produced in the order given in the word list. I experimented with using a priority queue for this, but the queue was a significant performance bottleneck.