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 crate::{
@ -11,6 +13,7 @@ use crate::{
LatLon,
};
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Coordinates {
pub latlon: LatLon,

View File

@ -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<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
/// Get an encoded address from a coordinate
#[wasm_bindgen]
pub fn from_coordinate(i: &str) -> Result<EncodedAddress, String> {
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<EncodedAddress, String> {
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<Self, Self::Error> {
fn from_str(s: &str) -> Result<Self, Self::Err> {
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<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())?;
// 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() {