From e8555e4095733b994ced3d3b77eb0f63774a36fc Mon Sep 17 00:00:00 2001 From: Austen Adler Date: Wed, 15 Feb 2023 19:16:57 -0500 Subject: [PATCH] Continue work on words --- Cargo.lock | 21 ++++++++++++++++ types/Cargo.toml | 1 + types/build.rs | 29 ++++++++++++++-------- types/src/lib.rs | 62 +++++++++++++++++++++++++++++++++--------------- 4 files changed, 84 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c16e91f..586d22d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -284,6 +284,26 @@ dependencies = [ "serde", ] +[[package]] +name = "thiserror" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "types" version = "0.1.0" @@ -292,6 +312,7 @@ dependencies = [ "phf", "phf_codegen", "serde", + "thiserror", ] [[package]] diff --git a/types/Cargo.toml b/types/Cargo.toml index e26f6e0..2d3a069 100644 --- a/types/Cargo.toml +++ b/types/Cargo.toml @@ -8,6 +8,7 @@ edition = "2021" [dependencies] serde={version="1", features=["derive"]} phf="0.11" +thiserror = "1.0.38" [build-dependencies] serde={version="1", features=["derive"]} diff --git a/types/build.rs b/types/build.rs index f86a00b..023b862 100644 --- a/types/build.rs +++ b/types/build.rs @@ -22,7 +22,16 @@ fn main() { .unwrap(); // Write it to an array containing all words - { + write_words(&mut file, &words); + + // Make a mapping of all caps word to a reference to the `Word` entry + write_word_map(&mut file, &words); + + // Make a mapping of numbers to `Word`s + write_number_to_words(&mut file, &words); +} + +fn write_words(mut file: impl Write, words: &[Word]) { writeln!( &mut file, r#"/// Static array of `Word` @@ -31,13 +40,12 @@ pub const WORDS: &[Word] = &["# .unwrap(); for result in words.iter() { - writeln!(&mut file, "\n{result:?},").unwrap(); + writeln!(&mut file, "\t{result:?},").unwrap(); } - } writeln!(&mut file, "];\n").unwrap(); + } - // Make a mapping of all caps word to a reference to the `Word` entry - { +fn write_word_map(mut file: impl Write, words: &[Word]) { let mut word_map = phf_codegen::Map::new(); for (idx, word) in words.iter().enumerate() { let idx_str = format!("&WORDS[{idx}]"); @@ -50,11 +58,10 @@ pub const WORDS: &[Word] = &["# {};"#, word_map.build() ) + .unwrap(); } - .unwrap(); - // Make a mapping of numbers to `Word`s - { +fn write_number_to_words(mut file: impl Write, words: &[Word]) { let word_number_to_idx = words .iter() .enumerate() @@ -63,9 +70,11 @@ pub const WORDS: &[Word] = &["# writeln!( &mut file, - "pub const NUMBER_TO_WORD: &[&[&'static Word]] = &[" + // "pub const NUMBER_TO_WORDS: &[&[usize]] = &[" + "pub const NUMBER_TO_WORDS: &[&[&'static Word]] = &[" ) .unwrap(); + for entry in word_number_to_idx .as_slice() .group_by(|(number1, _idx1), (number2, _idx2)| number1 == number2) @@ -73,13 +82,13 @@ pub const WORDS: &[Word] = &["# write!(&mut file, "\t&[",).unwrap(); for idx in entry.iter().map(|(_w, idx)| idx) { + // write!(&mut file, "{idx},").unwrap(); write!(&mut file, "&WORDS[{idx}],").unwrap(); } writeln!(&mut file, "],").unwrap(); } writeln!(&mut file, "];\n").unwrap(); } -} #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct Word { diff --git a/types/src/lib.rs b/types/src/lib.rs index 92d2e93..666f961 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -1,3 +1,4 @@ +use thiserror::Error; include!(concat!(env!("OUT_DIR"), "/codegen.rs")); #[derive(Debug, Clone, PartialEq)] @@ -18,22 +19,45 @@ pub struct Address<'a> { words: [Word<'a>; 3], } -// /// Find a word -// /// -// /// ```rust -// /// use static_data::find_country; -// /// -// /// assert!(find_country("US").is_some()); -// /// assert!(find_country("UnItEd StAtEs").is_some()); -// /// assert!(find_country("abcd").is_none()); -// /// ``` -// pub fn find_country(s: S) -> Option<&'static Country<'static>> -// where -// S: AsRef, -// { -// // TODO: Decide weather uppercasing is too slow -// COUNTRY_MAP -// .get(s.as_ref()) -// .or_else(|| COUNTRY_MAP.get(&s.as_ref().to_uppercase())) -// .copied() -// } +/// Helper function that gets the mapped number from a word +/// +/// ```rust +/// use types::get_number; +/// +/// assert!(get_number("ThE").is_ok()); +/// assert!(get_number("AsDf").is_err()); +/// ``` +pub fn get_number(maybe_word: S) -> Result +where + S: AsRef, +{ + get_word(maybe_word).map(|w| w.number) +} + +/// Gets a word from the word map +/// +/// ```rust +/// use types::get_word; +/// +/// assert!(get_word("THE").is_ok()); +/// assert!(get_word("the").is_ok()); +/// assert!(get_word("tHe").is_ok()); +/// assert!(get_word("ASDFASDF").is_err()); +/// ``` +pub fn get_word(maybe_word: S) -> Result<&'static Word<'static>, Error> +where + S: AsRef, +{ + WORD_MAP + .get(&maybe_word.as_ref().trim().to_ascii_uppercase()) + .copied() + .ok_or(Error::WordNotFound) +} + +#[derive(Error, Debug)] +pub enum Error { + #[error("Word not found")] + WordNotFound, + #[error("The requested number is out of bounds")] + NumberOutOfBounds, +}