diff --git a/spatial-coordinate-systems/src/all.rs b/spatial-coordinate-systems/src/all.rs index 678edc3..6b1be6b 100644 --- a/spatial-coordinate-systems/src/all.rs +++ b/spatial-coordinate-systems/src/all.rs @@ -1,3 +1,5 @@ +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; use std::str::FromStr; use crate::{ @@ -11,6 +13,7 @@ use crate::{ LatLon, }; +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Coordinates { pub latlon: LatLon, diff --git a/xpin-wasm/src/lib.rs b/xpin-wasm/src/lib.rs index aeffd3a..2349b3f 100644 --- a/xpin-wasm/src/lib.rs +++ b/xpin-wasm/src/lib.rs @@ -33,7 +33,6 @@ impl EncodedAddress { /// Get the string representation of the encoded value #[wasm_bindgen(js_name = getCoordsRepr)] - // TODO: Do not return option pub fn get_coords_repr(&self) -> String { self.src_coords.to_string() } @@ -50,51 +49,25 @@ impl EncodedAddress { .map(|s| s.to_string()) } - /// Get an encoded address from a latitude/longitude - #[wasm_bindgen] - pub fn from_lat_lon(lat: f64, lon: f64) -> Result { - Self::try_from( - xpin::Address::from_lat_lon(lat, lon) - .as_ref() - .map_err(|e| e.to_string())?, - ) - .map_err(|e| e.to_string()) - } - - /// Get an encoded address from a latitude/longitude + /// Get an encoded address from a coordinate #[wasm_bindgen] pub fn from_coordinate(i: &str) -> Result { - console_error_panic_hook::set_once(); - - let src_coords = Coordinate::from_str(i) - .map_err(|e| format!("Could not parse str {i:?} as a coordinate {e:?}"))?; - - let src_latlon = LatLon::from(&src_coords); - - let mut ret = Self::try_from( - xpin::Address::from_lat_lon(src_latlon.get_lat(), src_latlon.get_lon()) - .as_ref() - .map_err(|e| e.to_string())?, - ) - .map_err(|e| e.to_string())?; - - ret.src_coords = ret - .src_coords - .try_as_type(&src_coords.get_type().into()) - .map_err(|e| e.to_string())? - .into(); - - Ok(ret) + Self::from_str(i) } + /// Get an encoded address from an xpin address #[wasm_bindgen] pub fn from_address(addr_str: &str) -> Result { - Self::try_from( - xpin::Address::from_str(addr_str) - .as_ref() - .map_err(|e| e.to_string())?, - ) - .map_err(|e| e.to_string()) + let (lat, lon) = xpin::Address::from_str(addr_str) + .as_ref() + .map_err(|e| e.to_string())? + .as_lat_lon(); + + // TODO: Do not allocate a string here + let src_coords = + Coordinate::from_str(&format!("{}, {}", lat, lon)).map_err(|e| e.to_string())?; + + Self::try_from(src_coords) } } @@ -122,36 +95,62 @@ impl From<&spatial_coordinate_systems::all::Coordinates> for Coordinates { } } -impl TryFrom<&'_ Address<'_>> for EncodedAddress { - type Error = String; +impl FromStr for EncodedAddress { + type Err = String; - fn try_from(addr: &Address) -> Result { + fn from_str(s: &str) -> Result { console_error_panic_hook::set_once(); - let (lat, lon) = addr.as_lat_lon(); - // TODO: Do not allocate a string here - let src_coords = - Coordinate::from_str(&format!("{}, {}", lat, lon)).map_err(|e| e.to_string())?; + // The coordinates as encoded by the user + let src_coords = Coordinate::from_str(s) + .map_err(|e| format!("Could not parse str {s:?} as a coordinate {e:?}"))?; - let all_coordinates = spatial_coordinate_systems::all::Coordinates::try_from(&src_coords) + Self::try_from(src_coords) + } +} + +impl TryFrom for EncodedAddress { + type Error = String; + + fn try_from(src_coords: Coordinate) -> Result { + console_error_panic_hook::set_once(); + + // The latitude and longitude encoded by the user + let src_latlon = LatLon::from(&src_coords); + + // The encoded xpin address + let addr = xpin::Address::from_lat_lon(src_latlon.get_lat(), src_latlon.get_lon()) .map_err(|e| e.to_string())?; + // The latitude and longituded encoded by the xpin address + let (addr_lat, addr_lon) = addr.as_lat_lon(); + + // The coordinates as encoded by the xpin address + let addr_coordinates = spatial_coordinate_systems::all::Coordinates::try_from( + LatLon::new(addr_lat, addr_lon) + .map_err(|e| format!("Error converting xpin latlon to latlon: {e:?}"))?, + ) + .map_err(|e| e.to_string())?; + Ok(Self { address: addr.to_string(), - lat_lon: Box::new([lat, lon]), - src_coords, - coordinate_urls: CoordinateUrls::try_from(all_coordinates.latlon) + lat_lon: Box::new([addr_lat, addr_lon]), + src_coords: src_coords + .try_as_type(&src_coords.get_type().into()) .map_err(|e| e.to_string())? .into(), - decimal_degrees: format!("{}, {}", lat, lon), - all_coordinates: Coordinates::from(&all_coordinates), + coordinate_urls: CoordinateUrls::try_from(addr_coordinates.latlon) + .map_err(|e| e.to_string())? + .into(), + decimal_degrees: format!("{}, {}", addr_lat, addr_lon), + all_coordinates: Coordinates::from(&addr_coordinates), }) } } #[cfg(test)] mod tests { - // use super::*; + use super::*; #[test] fn test_general() {