Cleanup xpin_wasm encoding

This commit is contained in:
Austen Adler 2023-04-18 11:23:13 -04:00
parent cdf0c81c20
commit 98605cbab0
2 changed files with 56 additions and 54 deletions

View File

@ -1,3 +1,5 @@
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use std::str::FromStr; use std::str::FromStr;
use crate::{ use crate::{
@ -11,6 +13,7 @@ use crate::{
LatLon, LatLon,
}; };
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Coordinates { pub struct Coordinates {
pub latlon: LatLon, pub latlon: LatLon,

View File

@ -33,7 +33,6 @@ impl EncodedAddress {
/// Get the string representation of the encoded value /// Get the string representation of the encoded value
#[wasm_bindgen(js_name = getCoordsRepr)] #[wasm_bindgen(js_name = getCoordsRepr)]
// TODO: Do not return option
pub fn get_coords_repr(&self) -> String { pub fn get_coords_repr(&self) -> String {
self.src_coords.to_string() self.src_coords.to_string()
} }
@ -50,51 +49,25 @@ impl EncodedAddress {
.map(|s| s.to_string()) .map(|s| s.to_string())
} }
/// Get an encoded address from a latitude/longitude /// Get an encoded address from a coordinate
#[wasm_bindgen]
pub fn from_lat_lon(lat: f64, lon: f64) -> Result<EncodedAddress, String> {
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
#[wasm_bindgen] #[wasm_bindgen]
pub fn from_coordinate(i: &str) -> Result<EncodedAddress, String> { pub fn from_coordinate(i: &str) -> Result<EncodedAddress, String> {
console_error_panic_hook::set_once(); Self::from_str(i)
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)
} }
/// Get an encoded address from an xpin address
#[wasm_bindgen] #[wasm_bindgen]
pub fn from_address(addr_str: &str) -> Result<EncodedAddress, String> { pub fn from_address(addr_str: &str) -> Result<EncodedAddress, String> {
Self::try_from( let (lat, lon) = xpin::Address::from_str(addr_str)
xpin::Address::from_str(addr_str) .as_ref()
.as_ref() .map_err(|e| e.to_string())?
.map_err(|e| e.to_string())?, .as_lat_lon();
)
.map_err(|e| e.to_string()) // 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 { impl FromStr for EncodedAddress {
type Error = String; type Err = String;
fn try_from(addr: &Address) -> Result<Self, Self::Error> { fn from_str(s: &str) -> Result<Self, Self::Err> {
console_error_panic_hook::set_once(); console_error_panic_hook::set_once();
let (lat, lon) = addr.as_lat_lon(); // The coordinates as encoded by the user
// TODO: Do not allocate a string here let src_coords = Coordinate::from_str(s)
let src_coords = .map_err(|e| format!("Could not parse str {s:?} as a coordinate {e:?}"))?;
Coordinate::from_str(&format!("{}, {}", lat, lon)).map_err(|e| e.to_string())?;
let all_coordinates = spatial_coordinate_systems::all::Coordinates::try_from(&src_coords) Self::try_from(src_coords)
}
}
impl TryFrom<Coordinate> for EncodedAddress {
type Error = String;
fn try_from(src_coords: Coordinate) -> Result<Self, Self::Error> {
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())?; .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 { Ok(Self {
address: addr.to_string(), address: addr.to_string(),
lat_lon: Box::new([lat, lon]), lat_lon: Box::new([addr_lat, addr_lon]),
src_coords, src_coords: src_coords
coordinate_urls: CoordinateUrls::try_from(all_coordinates.latlon) .try_as_type(&src_coords.get_type().into())
.map_err(|e| e.to_string())? .map_err(|e| e.to_string())?
.into(), .into(),
decimal_degrees: format!("{}, {}", lat, lon), coordinate_urls: CoordinateUrls::try_from(addr_coordinates.latlon)
all_coordinates: Coordinates::from(&all_coordinates), .map_err(|e| e.to_string())?
.into(),
decimal_degrees: format!("{}, {}", addr_lat, addr_lon),
all_coordinates: Coordinates::from(&addr_coordinates),
}) })
} }
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
// use super::*; use super::*;
#[test] #[test]
fn test_general() { fn test_general() {