pub const WORDS: [&str; 256] = [
"acorn", "amber", "anchor", "apple", "apron", "javelin", "attic", "autumn", "badge", "bagel",
"bamboo", "banjo", "barrel", "basket", "beacon", "beetle", "bison", "blanket", "blossom",
"bottle", "bridge", "broom", "bubble", "bucket", "biscuit", "button", "cabin", "cactus",
"camel", "candle", "canoe", "canyon", "carpet", "carrot", "castle", "cedar", "cello", "cherry",
"chimney", "custard", "circus", "clover", "cobalt", "coconut", "coffee", "comet", "compass",
"copper", "coral", "denim", "cradle", "peacock", "cricket", "crystal", "cupcake", "curtain",
"daisy", "dolphin", "domino", "donkey", "dragon", "drum", "eagle", "echo", "elbow", "flamingo",
"engine", "falcon", "feather", "fiddle", "finch", "fossil", "fountain", "garden", "garlic",
"gecko", "ginger", "glacier", "goblet", "goose", "granite", "guitar", "hammer", "hammock",
"sailor", "harvest", "hazel", "helmet", "heron", "beaver", "honey", "iceberg", "igloo",
"island", "ivory", "jacket", "jaguar", "jasmine", "jelly", "jigsaw", "jungle", "kayak",
"kettle", "kitten", "koala", "ladder", "lantern", "lemon", "leopard", "lettuce", "lizard",
"llama", "lobster", "kangaroo", "lotus", "magnet", "mango", "marble", "prairie", "parsnip",
"glove", "gorilla", "mosaic", "muffin", "mushroom", "napkin", "nectar", "needle", "paprika",
"nutmeg", "oasis", "octopus", "olive", "onion", "orbit", "orchid", "ostrich", "otter",
"oyster", "oatmeal", "pyramid", "porridge", "panda", "toucan", "pasta", "peanut", "pebble",
"pelican", "pencil", "penguin", "saffron", "piano", "pickle", "pigeon", "pillow", "pirate",
"nebula", "magpie", "poodle", "poppy", "potato", "pretzel", "pumpkin", "puppet", "puzzle",
"quilt", "rabbit", "raccoon", "radish", "rainbow", "raisin", "raven", "ribbon", "river",
"spinach", "rocket", "rooster", "rubber", "saddle", "salmon", "tortoise", "satchel", "scarf",
"scooter", "shadow", "sheep", "shovel", "silver", "sketch", "loafer", "snail", "soccer",
"sofa", "sparrow", "spider", "sponge", "spoon", "squirrel", "stable", "stapler", "sticker",
"stork", "summer", "sunset", "sweater", "tablet", "clarinet", "teapot", "temple", "tennis",
"thimble", "thunder", "wombat", "tiger", "toaster", "turnip", "tractor", "trumpet", "tulip",
"tunnel", "vulture", "turtle", "umbrella", "unicorn", "velvet", "violet", "trombone",
"volcano", "waffle", "wagon", "walnut", "walrus", "goblin", "wasabi", "harp", "window",
"snowman", "sapphire", "pudding", "zebra", "zipper", "zucchini", "bronze", "cobweb", "dinghy",
"flannel", "gravel", "hedgehog", "kiwi", "lagoon", "mammoth", "platypus", "pistol", "quartz",
"sardine", "lentil",
];
#[must_use]
pub fn code_from(bytes: [u8; 4]) -> String {
bytes
.iter()
.map(|byte| WORDS[usize::from(*byte)])
.collect::<Vec<_>>()
.join(" ")
}
#[cfg(test)]
mod tests {
use super::{WORDS, code_from};
#[test]
fn pairing_words_are_distinct_lowercase_short_and_two_hundred_and_fifty_six() {
let mut seen = std::collections::BTreeSet::new();
for word in WORDS {
assert!(
word.len() >= 3 && word.len() <= 8,
"{word} is not short enough to say"
);
assert!(
word.bytes().all(|byte| byte.is_ascii_lowercase()),
"{word} is not lowercase ascii"
);
assert!(seen.insert(word), "{word} is listed twice");
}
assert_eq!(seen.len(), 256);
}
#[test]
fn pairing_code_takes_one_word_per_byte() {
assert_eq!(code_from([0, 1, 2, 255]), "acorn amber anchor lentil");
let code = code_from([7, 7, 7, 7]);
let words: Vec<&str> = code.split(' ').collect();
assert_eq!(words, ["autumn"; 4]);
}
}