Continue work on words

This commit is contained in:
Austen Adler 2023-02-15 19:16:57 -05:00
parent 3dff0167dd
commit e8555e4095
4 changed files with 84 additions and 29 deletions

21
Cargo.lock generated
View File

@ -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]]

View File

@ -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"]}

View File

@ -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 {

View File

@ -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: S) -> Option<&'static Country<'static>>
// where
// S: AsRef<str>,
// {
// // 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<S>(maybe_word: S) -> Result<u16, Error>
where
S: AsRef<str>,
{
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<S>(maybe_word: S) -> Result<&'static Word<'static>, Error>
where
S: AsRef<str>,
{
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,
}