diff --git a/src/osgb.rs b/src/osgb.rs index 86f763e..63edc98 100644 --- a/src/osgb.rs +++ b/src/osgb.rs @@ -1,5 +1,6 @@ use crate::constants::_500KM; use crate::grid::{coords_to_square, square_to_coords}; +use crate::utils::trim_string; use crate::{coordinates::point::Point as GridPoint, Error, Precision}; use geo_types::{LineString, Point, Polygon}; use std::fmt::Display; @@ -27,7 +28,7 @@ pub struct OSGB { impl OSGB { /// Creates a new grid reference from the given coordinates /// and precision. - /// + /// /// # Errors /// Returns an error if the given coordinates are out of bounds. /// @@ -251,11 +252,7 @@ impl FromStr for OSGB { type Err = Error; fn from_str(s: &str) -> Result { - let string: String = s - .to_uppercase() - .chars() - .filter(|c| !c.is_whitespace()) - .collect(); + let string: String = trim_string(s); match string.chars().next() { Some(c) => { diff --git a/src/osi.rs b/src/osi.rs index 7ceb0e7..c5b0e9b 100644 --- a/src/osi.rs +++ b/src/osi.rs @@ -1,3 +1,4 @@ +use crate::utils::trim_string; use crate::{coordinates::point::Point as GridPoint, Error, Precision}; use geo_types::{LineString, Point, Polygon}; use std::fmt::Display; @@ -18,7 +19,7 @@ pub struct OSI { impl OSI { /// Creates a new grid reference from the given coordinates /// and precision. - /// + /// /// # Errors /// Returns an error if the given coordinates are out of bounds. /// @@ -208,11 +209,7 @@ impl FromStr for OSI { type Err = Error; fn from_str(s: &str) -> Result { - let string: String = s - .to_uppercase() - .chars() - .filter(|c| !c.is_whitespace()) - .collect(); + let string: String = trim_string(s); let point: GridPoint = string.parse()?; Ok(Self { point }) diff --git a/src/utils.rs b/src/utils.rs index f1c489e..0d2303d 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -48,9 +48,22 @@ pub fn digits(s: &str) -> Result<(u32, u32, Precision), Error> { )) } +/// Removes all non-alphanumeric characters from string +/// and converts to uppercase for parsing. +pub fn trim_string(s: &str) -> String { + s.chars() + .filter(|c| !c.is_ascii_whitespace()) + .map(|c| c.to_ascii_uppercase()) + .collect() +} + #[cfg(test)] mod test { - use crate::{constants::*, utils::digits, Error, Precision}; + use crate::{ + constants::*, + utils::{digits, trim_string}, + Error, Precision, + }; #[test] fn parse_valid_digits() { @@ -81,4 +94,11 @@ mod test { )) ) } + + #[test] + fn trim_strings() { + assert_eq!(trim_string("so 14 5"), "SO145"); + assert_eq!(trim_string("So 222"), "SO222"); + assert_eq!(trim_string(" @ @ "), "@@"); + } }