From 7c2febdedbfa8bfae815e4da26e114365b338622 Mon Sep 17 00:00:00 2001 From: Julio Biason Date: Sun, 25 Oct 2020 15:12:30 -0300 Subject: [PATCH] Generating names, finally! --- Cargo.lock | 71 +++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/main.rs | 35 ++++++++++++++++++++++- src/repository.rs | 25 ++++++++++++++++- 4 files changed, 130 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 73da412..acd8f81 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,6 +26,12 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + [[package]] name = "clap" version = "2.33.0" @@ -41,6 +47,17 @@ dependencies = [ "vec_map", ] +[[package]] +name = "getrandom" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "hermit-abi" version = "0.1.8" @@ -61,11 +78,18 @@ name = "nrp" version = "0.1.0" dependencies = [ "clap", + "rand", "serde", "serde_derive", "toml", ] +[[package]] +name = "ppv-lite86" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c36fa947111f5c62a733b652544dd0016a43ce89619538a8ef92724a6f501a20" + [[package]] name = "proc-macro2" version = "1.0.24" @@ -84,6 +108,47 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom", + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core", +] + [[package]] name = "serde" version = "1.0.117" @@ -154,6 +219,12 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + [[package]] name = "winapi" version = "0.3.8" diff --git a/Cargo.toml b/Cargo.toml index f3f74dd..c755adf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,3 +10,4 @@ clap = "2.33" toml = "0.5" serde = "*" serde_derive = "*" +rand = "0.7" diff --git a/src/main.rs b/src/main.rs index 570b4a0..11456f2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,6 +20,12 @@ mod actions; mod args; mod repository; +#[derive(Debug)] +enum Error { + NoAdjectiveWith(String), + NoMetalWith(String), +} + fn main() { match args::parse() { Ok(x) => match x { @@ -37,7 +43,9 @@ fn main() { } actions::Action::MetalAdd(word) => repository::WordList::insert_metal(&word).unwrap(), actions::Action::MetalRm(word) => repository::WordList::remove_metal(&word).unwrap(), - _ => unimplemented!(), + actions::Action::Generate(description) => { + println!("{}", generate(&description).unwrap()); + } }, Err(x) => println!("Error {:?}", x), } @@ -52,3 +60,28 @@ fn show_words(list: &repository::WordStorage) { } } } + +fn generate(description: &str) -> Result { + let content = repository::WordList::load().unwrap(); + + let initials = String::from(description) + .trim() + .split_whitespace() + .map(|word| word.chars().nth(0).unwrap().to_string()) + .collect::>(); + let number_of_initials = initials.len() - 1; + + let mut result = Vec::new(); + for (pos, letter) in initials.iter().enumerate() { + result.push(if pos == number_of_initials { + content + .get_random_metal(&letter) + .map_err(|_| Error::NoMetalWith(letter.to_string()))? + } else { + content + .get_random_adjective(&letter) + .map_err(|_| Error::NoAdjectiveWith(letter.to_string()))? + }); + } + Ok(result.join(" ")) +} diff --git a/src/repository.rs b/src/repository.rs index c8ea93b..d8f3c91 100644 --- a/src/repository.rs +++ b/src/repository.rs @@ -3,6 +3,8 @@ use std::collections::BTreeSet; use std::fs::File; use std::io::{Read, Write}; +use rand::prelude::*; +use rand::thread_rng; use serde_derive::Deserialize; use serde_derive::Serialize; use toml; @@ -51,7 +53,7 @@ impl WordList { } /// Load the database - fn load() -> Result { + pub fn load() -> Result { if let Ok(mut fp) = File::open("database.toml") { let mut content = String::new(); fp.read_to_string(&mut content)?; @@ -76,6 +78,11 @@ impl WordList { Ok(repo.adjectives) } + /// Return a random adjective with the initial requested + pub fn get_random_adjective(&self, initial: &str) -> Result { + Self::get_random_word(&initial.to_lowercase(), &self.adjectives) + } + /// Add an adjective to the word list pub fn insert_adjective(adjective: &str) -> Result<(), WordListError> { let mut repo = Self::load()?; @@ -96,6 +103,11 @@ impl WordList { Ok(repo.metals) } + /// Return a random metal with the initial requested + pub fn get_random_metal(&self, initial: &str) -> Result { + Self::get_random_word(&initial.to_lowercase(), &self.metals) + } + /// Add a metal to the word list pub fn insert_metal(metal: &str) -> Result<(), WordListError> { let mut repo = Self::load()?; @@ -110,6 +122,17 @@ impl WordList { repo.save() } + fn get_random_word(initial: &str, storage: &WordStorage) -> Result { + let mut rng = thread_rng(); + Ok(storage + .get(initial) + .ok_or(WordListError::NoSuchWord)? + .iter() + .choose(&mut rng) + .ok_or(WordListError::NoSuchWord)? + .to_string()) + } + /// Generic function to insert words in the storage; the target points in which of the lists /// the word should be inserted. fn insert_word(word: &str, target: &mut WordStorage) -> Result<(), WordListError> {