diff --git a/README.md b/README.md index 5e1a06d..0a1d4a0 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,16 @@ assert_eq!( ); ``` +It is also possible to construct a [`GeoUri`] struct from coordinate tuples +using the [`TryFrom`](std::convert::TryFrom) trait: + +```rust +use geo_uri::GeoUri; + +let geo_uri = GeoUri::try_from((52.107, 5.134)).expect("valid coordinates"); +let geo_uri = GeoUri::try_from((52.107, 5.134, 3.6)).expect("valid coordinates"); +``` + ## License geo-uri-rs is licensed under the MIT license (see the `LICENSE` file or diff --git a/src/lib.rs b/src/lib.rs index 8696a49..1d12c7f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -212,6 +212,16 @@ impl Default for CoordRefSystem { /// # } /// ``` /// +/// It is also possible to construct a [`GeoUri`] struct from coordinate tuples +/// using the [`TryFrom`](std::convert::TryFrom) trait: +/// +/// ```rust +/// use geo_uri::GeoUri; +/// +/// let geo_uri = GeoUri::try_from((52.107, 5.134)).expect("valid coordinates"); +/// let geo_uri = GeoUri::try_from((52.107, 5.134, 3.6)).expect("valid coordinates"); +/// ``` +/// /// # See also /// /// For the proposed IEEE standard, see [RFC 5870](https://www.rfc-editor.org/rfc/rfc5870). @@ -458,6 +468,37 @@ impl TryFrom<&str> for GeoUri { } } +impl TryFrom<(f64, f64)> for GeoUri { + type Error = Error; + + fn try_from((latitude, longitude): (f64, f64)) -> Result { + let geo_uri = GeoUri { + latitude, + longitude, + ..Default::default() + }; + geo_uri.validate()?; + + Ok(geo_uri) + } +} + +impl TryFrom<(f64, f64, f64)> for GeoUri { + type Error = Error; + + fn try_from((latitude, longitude, altitude): (f64, f64, f64)) -> Result { + let geo_uri = GeoUri { + latitude, + longitude, + altitude: Some(altitude), + ..Default::default() + }; + geo_uri.validate()?; + + Ok(geo_uri) + } +} + impl PartialEq for GeoUri { fn eq(&self, other: &Self) -> bool { // In the WGS-84 CRS the the longitude is ignored for the poles. @@ -765,6 +806,36 @@ mod tests { assert_eq!(geo_uri.altitude, None); assert_eq!(geo_uri.uncertainty, None); + let geo_uri = GeoUri::try_from((51.107, 5.134))?; + assert_float_eq!(geo_uri.latitude, 51.107, abs <= 0.001); + assert_float_eq!(geo_uri.longitude, 5.134, abs <= 0.001); + assert_eq!(geo_uri.altitude, None); + assert_eq!(geo_uri.uncertainty, None); + + assert_eq!( + GeoUri::try_from((100.0, 5.134)), + Err(Error::OutOfRangeLatitude) + ); + assert_eq!( + GeoUri::try_from((51.107, -200.0)), + Err(Error::OutOfRangeLongitude) + ); + + let geo_uri = GeoUri::try_from((51.107, 5.134, 3.6))?; + assert_float_eq!(geo_uri.latitude, 51.107, abs <= 0.001); + assert_float_eq!(geo_uri.longitude, 5.134, abs <= 0.001); + assert_float_eq!(geo_uri.altitude.unwrap(), 3.6, abs <= 0.1); + assert_eq!(geo_uri.uncertainty, None); + + assert_eq!( + GeoUri::try_from((100.0, 5.134, 3.6)), + Err(Error::OutOfRangeLatitude) + ); + assert_eq!( + GeoUri::try_from((51.107, -200.0, 3.6)), + Err(Error::OutOfRangeLongitude) + ); + Ok(()) }