From 22549f378a14b533b7ce7343947b83afd8a2e3b7 Mon Sep 17 00:00:00 2001 From: Austen Adler Date: Thu, 16 Mar 2023 01:18:59 -0400 Subject: [PATCH] Minor fixes --- src/lib.rs | 75 ++++++++++++------------ web-frontend/src/lib/AddressInput.svelte | 4 +- web-frontend/src/routes/app/+page.svelte | 22 ++++++- 3 files changed, 59 insertions(+), 42 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 05020e7..429d361 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,8 +31,8 @@ pub const V0_MIN_NUMBER: u32 = 1024; #[derive(Error, Debug, Eq, PartialEq)] pub enum Error { /// The given word is not in the wordlist - #[error("Word does not exist: {0}")] - WordDoesNotExist(String), + #[error("Words do not exist: {0:?}")] + WordsDoNotExist(Vec), /// The encoded version bit is not supported by this version of the crate #[error("Unimplemented version: {0}")] UnimplementedVersion(u8), @@ -43,7 +43,7 @@ pub enum Error { #[error("The string given is not ascii")] NonAscii, /// The number of components given to decode is incorrect - #[error("Wrong number of components")] + #[error("Need one number and three words")] WrongComponentCount, /// No number component was found /// @@ -58,6 +58,9 @@ pub enum Error { /// This is the case when either lat or lon is f64::NAN #[error("Invalid latitude or longitude")] NaNLatLng, + + #[error("Words cannot be repeated")] + RepeatedWords, } #[allow(clippy::doc_markdown)] @@ -131,7 +134,6 @@ impl Address<'_> { /// This will return [`Error::NaNLatLng`] when the latitude or longitude are not valid /// /// See [`Error::NaNLatLng`] for the valid values - pub fn from_lat_lon(lat: f64, lon: f64) -> Result { let cellid = conversions::lat_lon_to_cellid(lat, lon)?; @@ -160,21 +162,39 @@ impl Address<'_> { return Err(Error::WrongComponentCount); } - // Convert each word component into a word, returning an error if any do not match - let words = TryInto::<[&'static Word; 3]>::try_into( - word_components - .iter() - .map(|w| { - words::get_word(w).ok_or_else(|| Error::WordDoesNotExist((*w).to_string())) - }) - .collect::, Error>>()?, - ) - // This unwrap is okay because we just checked to make sure the number of word components was 3 - .unwrap(); + // Check that each word exists + let mut errors = vec![]; + let mut words = vec![]; + + for word in word_components { + match words::get_word(word) { + Some(w) => words.push(w), + None => errors.push(word.to_ascii_uppercase()), + } + } + + if !errors.is_empty() { + return Err(Error::WordsDoNotExist(errors)); + } + + // Check that each word is not repeated + // TODO: This will be handled by the call to get_words_multi later + { + let mut word_numbers: Vec = words.iter().map(|w| w.number).collect(); + word_numbers.sort(); + let prev_len = word_numbers.len(); + word_numbers.dedup(); + let cur_len = word_numbers.len(); + + if prev_len != cur_len { + return Err(Error::RepeatedWords); + } + } Ok(Self { number, - words, + // This unwrap is okay because we just checked to make sure the number of word components was 3 + words: TryInto::<[&'static Word; 3]>::try_into(words).unwrap(), version: Version::V0, }) } @@ -202,17 +222,6 @@ impl Address<'_> { } } -/// Extracts a version number from a number -/// -/// The version number is set by the two bits 11 and 12 -// TODO: impl TryFrom ? -// const fn extract_version(number: Number) -> Result { -// match ((number >> 10) & 0b11) as u8 { -// 0 => Ok(Version::V0), -// v => Err(Error::UnimplementedVersion(v)), -// } -// } - impl Display for Address<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( @@ -243,18 +252,6 @@ mod tests { }; } - // #[test] - // fn test_extract_version() { - // assert_eq!(extract_version(0b0000_0000_0000), 0b00); - // assert_eq!(extract_version(0b1100_0000_0000), 0b11); - // assert_eq!(extract_version(0b0100_0000_0000), 0b01); - // assert_eq!(extract_version(0b1000_0000_0000), 0b10); - // assert_eq!(extract_version(0b11 << 10), 0b11); - // assert_eq!(extract_version(0b00 << 10), 0b00); - // assert_eq!(extract_version(0b10 << 10), 0b10); - // assert_eq!(extract_version(0b01 << 10), 0b01); - // } - #[test] fn test_address_from_str() { for i in &[ diff --git a/web-frontend/src/lib/AddressInput.svelte b/web-frontend/src/lib/AddressInput.svelte index 6117cc5..8d4bdfa 100644 --- a/web-frontend/src/lib/AddressInput.svelte +++ b/web-frontend/src/lib/AddressInput.svelte @@ -24,9 +24,9 @@ placeholder="Enter address">
- + Loading WebAssembly module...

{:then} -

Current cursor: {addr.address} ({addr.latLon}) => ({latlng.lat}, {latlng.lng})

+

Address: {addr.address}

+

({addr.latLon}) => ({latlng.lat}, {latlng.lng})

+
+ + + + +
+ {:catch message} Could not start core module