Compare commits
No commits in common. "v0.2.0" and "v0.1.1" have entirely different histories.
5 changed files with 33 additions and 414 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,4 +1,2 @@
|
|||
/target
|
||||
Cargo.lock
|
||||
.vim
|
||||
.vscode
|
||||
|
|
15
CHANGELOG.md
15
CHANGELOG.md
|
@ -7,18 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.2.0] - 2022-10-01
|
||||
|
||||
### Added
|
||||
|
||||
* Add support for converting from/to `Url` structs (#1)
|
||||
* Add support for (de)serializing via serde (#2)
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fix documentation and comment types and improve examples
|
||||
* Make the crate adhere to the [Rust API guidelines](https://rust-lang.github.io/api-guidelines/)
|
||||
|
||||
## [0.1.1] - 2022-09-30
|
||||
|
||||
### Added
|
||||
|
@ -30,6 +18,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
* Fix some small errors in the documentation
|
||||
|
||||
[Unreleased]: https://git.luon.net/paul/geo-uri-rs/compare/v0.2.0...HEAD
|
||||
[0.2.0]: https://git.luon.net/paul/geo-uri-rs/compare/v0.1.1..v0.2.0
|
||||
[Unreleased]: https://git.luon.net/paul/geo-uri-rs/compare/v0.1.1...HEAD
|
||||
[0.1.1]: https://git.luon.net/paul/geo-uri-rs/commits/tag/v0.1.1
|
||||
|
|
18
Cargo.toml
18
Cargo.toml
|
@ -1,30 +1,18 @@
|
|||
[package]
|
||||
name = "geo-uri"
|
||||
version = "0.2.0"
|
||||
version = "0.1.1"
|
||||
authors = ["Paul van Tilburg <paul@luon.net>"]
|
||||
edition = "2021"
|
||||
rust-version = "1.60.0"
|
||||
description = "A crate for parsing and generating uniform resource identifiers for geographic locations (geo URIs)"
|
||||
homepage = "https://git.luon.net/paul/geo-uri-rs"
|
||||
repository = "https://git.luon.net/paul/geo-uri-rs.git"
|
||||
readme = "README.md"
|
||||
repository = "https://git.luon.net/paul/geo-uri-rs"
|
||||
license = "MIT"
|
||||
keywords = ["geolocation", "uri", "parser", "rfc5870"]
|
||||
categories = ["parser-implementations", "web-programming", "encoding"]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[features]
|
||||
url = ["dep:url"]
|
||||
serde = ["dep:serde"]
|
||||
|
||||
[dependencies]
|
||||
derive_builder = "0.11.2"
|
||||
serde = { version = "1.0.145", optional = true }
|
||||
thiserror = "1.0.35"
|
||||
url = { version = "2.3.1", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
float_eq = "1.0.0"
|
||||
serde_test = "1.0.145"
|
||||
|
|
64
README.md
64
README.md
|
@ -17,14 +17,13 @@ Just run the following to add this library to your project:
|
|||
```sh
|
||||
$ cargo add geo-uri
|
||||
Updating crates.io index
|
||||
Adding geo-uri vX.Y.Z to dependencies.
|
||||
Adding thiserror vX.Y.Z to dependencies.
|
||||
```
|
||||
|
||||
### Parsing
|
||||
|
||||
Use either the [`TryFrom`](std::convert::TryFrom) trait or the
|
||||
[`parse`](str::parse) method on strings to parse a geo URI string into a
|
||||
[`GeoUri`] struct:
|
||||
Use either the [`FromStr`](std::str::FromStr) or
|
||||
[`TryFrom`](std::convert::TryFrom) traits to parse a geo URI string:
|
||||
|
||||
```rust
|
||||
use geo_uri::GeoUri;
|
||||
|
@ -35,7 +34,8 @@ assert_eq!(geo_uri.longitude(), 5.134);
|
|||
assert_eq!(geo_uri.altitude(), Some(3.6));
|
||||
assert_eq!(geo_uri.uncertainty(), Some(1000.0));
|
||||
|
||||
let geo_uri: GeoUri = "geo:52.107,5.134;u=2000.0".parse().expect("valid geo URI");
|
||||
use std::str::FromStr;
|
||||
let geo_uri = GeoUri::from_str("geo:52.107,5.134;u=2000.0").expect("valid geo URI");
|
||||
assert_eq!(geo_uri.latitude(), 52.107);
|
||||
assert_eq!(geo_uri.longitude(), 5.134);
|
||||
assert_eq!(geo_uri.altitude(), None);
|
||||
|
@ -56,9 +56,9 @@ assert_eq!(geo_uri.uncertainty(), None);
|
|||
|
||||
### Generating
|
||||
|
||||
Use the [`GeoUriBuilder`] to construct a [`GeoUri`] struct.
|
||||
Use the `GeoUriBuilder` to construct a `GeoUri` struct.
|
||||
Then, use either the [`ToString`](std::string::ToString) or
|
||||
[`Display`](std::fmt::Display) trait to generate a geo URI string:
|
||||
[`Display`](std::fmt::Display) trait to generate an geo URI string:
|
||||
|
||||
```rust
|
||||
use geo_uri::GeoUri;
|
||||
|
@ -80,56 +80,6 @@ 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");
|
||||
```
|
||||
|
||||
### Feature: `url`
|
||||
|
||||
You can enable the `url` feature to convert from and to
|
||||
[`Url`](https://docs.rs/url/2/url/struct.Url.html) structs from the
|
||||
[`url`](https://docs.rs/url/2/url) crate.
|
||||
|
||||
Enable the feature in your `Cargo.toml` first:
|
||||
|
||||
```toml
|
||||
geo-uri = { version = "X.Y.Z", features = ["url"] }
|
||||
```
|
||||
|
||||
Then you can do:
|
||||
|
||||
```rust
|
||||
use geo_uri::GeoUri;
|
||||
use url::Url;
|
||||
|
||||
let url = Url::parse("geo:52.107,5.134,3.6").expect("valid URL");
|
||||
let geo_uri = GeoUri::try_from(&url).expect("valid geo URI");
|
||||
let geo_url = Url::from(geo_uri);
|
||||
|
||||
assert_eq!(url, geo_url);
|
||||
```
|
||||
|
||||
Note that it is always possible to transform a [`GeoUri`] into an [`Url`], but
|
||||
not always the other way around! This is because the format of the coordinates
|
||||
and parameters after the URI scheme "geo:" may be invalid!
|
||||
|
||||
### Feature: `serde`
|
||||
|
||||
If you enable the `serde` feature, [`GeoUri`] will implement
|
||||
[`serde::Serialize`](https://docs.rs/serde/1/serde/trait.Serialize.html) and
|
||||
[`serde::Deserialize`](https://docs.rs/serde/1/serde/trait.Deserialize.html).
|
||||
See the [serde](https://serde.rs) documentation for more information.
|
||||
|
||||
```toml
|
||||
geo-uri = { version = "X.Y.Z", features = ["serde"] }
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
geo-uri-rs is licensed under the MIT license (see the `LICENSE` file or
|
||||
|
|
346
src/lib.rs
346
src/lib.rs
|
@ -1,4 +1,3 @@
|
|||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
#![doc = include_str!("../README.md")]
|
||||
#![warn(
|
||||
clippy::all,
|
||||
|
@ -21,14 +20,7 @@ use std::num::ParseFloatError;
|
|||
use std::str::FromStr;
|
||||
|
||||
use derive_builder::Builder;
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{
|
||||
de::{Deserialize, Visitor},
|
||||
ser::Serialize,
|
||||
};
|
||||
use thiserror::Error;
|
||||
#[cfg(feature = "url")]
|
||||
use url::Url;
|
||||
|
||||
/// The scheme name of a geo URI.
|
||||
const URI_SCHEME_NAME: &str = "geo";
|
||||
|
@ -115,11 +107,6 @@ impl CoordRefSystem {
|
|||
/// Err(Error::OutOfRangeLongitude)
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// An error is returned if the latitude/longitude is out of range with respect to the
|
||||
/// coordinate reference system.
|
||||
pub fn validate(&self, latitude: f64, longitude: f64) -> Result<(), Error> {
|
||||
// This holds only for WGS-84, but it is the only one supported right now!
|
||||
if !(-90.0..=90.0).contains(&latitude) {
|
||||
|
@ -151,47 +138,36 @@ impl Default for CoordRefSystem {
|
|||
///
|
||||
/// ```rust
|
||||
/// use geo_uri::GeoUri;
|
||||
/// # use geo_uri::Error;
|
||||
///
|
||||
/// # fn main() -> Result<(), Error> {
|
||||
/// let geo_uri = GeoUri::try_from("geo:52.107,5.134,3.6;u=1000")?;
|
||||
/// let geo_uri = GeoUri::try_from("geo:52.107,5.134,3.6;u=1000").expect("valid geo URI");
|
||||
/// assert_eq!(geo_uri.latitude(), 52.107);
|
||||
/// assert_eq!(geo_uri.longitude(), 5.134);
|
||||
/// assert_eq!(geo_uri.altitude(), Some(3.6));
|
||||
/// assert_eq!(geo_uri.uncertainty(), Some(1000.0));
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// or by calling the [`parse`](str::parse) method on a string (using the [`TryFrom`] trait):
|
||||
/// or by using the [`TryFrom`] trait:
|
||||
/// ```
|
||||
/// use geo_uri::GeoUri;
|
||||
/// # use geo_uri::Error;
|
||||
/// use std::str::FromStr;
|
||||
///
|
||||
/// # fn main() -> Result<(), Error> {
|
||||
/// let geo_uri: GeoUri = "geo:52.107,5.134;u=2000.0".parse()?;
|
||||
/// let geo_uri = GeoUri::from_str("geo:52.107,5.134;u=2000.0").expect("valid geo URI");
|
||||
/// assert_eq!(geo_uri.latitude(), 52.107);
|
||||
/// assert_eq!(geo_uri.longitude(), 5.134);
|
||||
/// assert_eq!(geo_uri.altitude(), None);
|
||||
/// assert_eq!(geo_uri.uncertainty(), Some(2000.0));
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// It is also possible to call the parse function directly:
|
||||
///
|
||||
/// ```rust
|
||||
/// use geo_uri::GeoUri;
|
||||
/// # use geo_uri::Error;
|
||||
///
|
||||
/// # fn main() -> Result<(), Error> {
|
||||
/// let geo_uri = GeoUri::parse("geo:52.107,5.134,3.6")?;
|
||||
/// let geo_uri = GeoUri::parse("geo:52.107,5.134,3.6").expect("valid geo URI");
|
||||
/// assert_eq!(geo_uri.latitude(), 52.107);
|
||||
/// assert_eq!(geo_uri.longitude(), 5.134);
|
||||
/// assert_eq!(geo_uri.altitude(), Some(3.6));
|
||||
/// assert_eq!(geo_uri.uncertainty(), None);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// ## Generating
|
||||
|
@ -200,14 +176,13 @@ impl Default for CoordRefSystem {
|
|||
///
|
||||
/// ```rust
|
||||
/// use geo_uri::GeoUri;
|
||||
/// # use geo_uri::GeoUriBuilderError;
|
||||
///
|
||||
/// # fn main() -> Result<(), GeoUriBuilderError> {
|
||||
/// let geo_uri = GeoUri::builder()
|
||||
/// .latitude(52.107)
|
||||
/// .longitude(5.134)
|
||||
/// .uncertainty(1_000.0)
|
||||
/// .build()?;
|
||||
/// .build()
|
||||
/// .unwrap();
|
||||
/// assert_eq!(
|
||||
/// geo_uri.to_string(),
|
||||
/// String::from("geo:52.107,5.134;u=1000")
|
||||
|
@ -216,18 +191,6 @@ impl Default for CoordRefSystem {
|
|||
/// format!("{geo_uri}"),
|
||||
/// String::from("geo:52.107,5.134;u=1000")
|
||||
/// );
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// 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
|
||||
|
@ -273,10 +236,6 @@ impl GeoUri {
|
|||
///
|
||||
/// For the geo URI scheme syntax, see the propsed IEEE standard
|
||||
/// [RFC 5870](https://www.rfc-editor.org/rfc/rfc5870#section-3.3).
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Will return an error if the parsing fails in any way.
|
||||
pub fn parse(uri: &str) -> Result<Self, Error> {
|
||||
let uri = uri.to_ascii_lowercase();
|
||||
let uri_path = uri.strip_prefix("geo:").ok_or(Error::MissingScheme)?;
|
||||
|
@ -334,17 +293,22 @@ impl GeoUri {
|
|||
Some(_) | None => (CoordRefSystem::default(), None),
|
||||
};
|
||||
|
||||
// Validate the geo URI before returning it.
|
||||
let geo_uri = GeoUri {
|
||||
// Validate the parsed values.
|
||||
crs.validate(latitude, longitude)?;
|
||||
// FIXME: Move this into the validator? This code is duplicate now.
|
||||
if let Some(unc) = uncertainty {
|
||||
if unc < 0.0 {
|
||||
return Err(Error::OutOfRangeUncertainty);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(GeoUri {
|
||||
crs,
|
||||
latitude,
|
||||
longitude,
|
||||
altitude,
|
||||
uncertainty,
|
||||
};
|
||||
geo_uri.validate()?;
|
||||
|
||||
Ok(geo_uri)
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the latitude coordinate.
|
||||
|
@ -354,10 +318,7 @@ impl GeoUri {
|
|||
|
||||
/// Changes the latitude coordinate.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// If the latitude is out of range for the coordinate reference system, an error will be
|
||||
/// returned.
|
||||
/// The latitude may be out of range for the coordinate reference system.
|
||||
pub fn set_latitude(&mut self, latitude: f64) -> Result<(), Error> {
|
||||
self.crs.validate(latitude, self.longitude)?;
|
||||
self.latitude = latitude;
|
||||
|
@ -372,10 +333,7 @@ impl GeoUri {
|
|||
|
||||
/// Changes the longitude coordinate.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// If the longitude is out of range for the coordinate reference system, an error will be
|
||||
/// returned.
|
||||
/// The longitude may be out of range for the coordinate reference system.
|
||||
pub fn set_longitude(&mut self, longitude: f64) -> Result<(), Error> {
|
||||
self.crs.validate(self.latitude, longitude)?;
|
||||
self.longitude = longitude;
|
||||
|
@ -400,9 +358,7 @@ impl GeoUri {
|
|||
|
||||
/// Changes the uncertainty around the location.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// If the uncertainty distance is not zero or positive, an error will be returned.
|
||||
/// The uncertainty distance must be positive.
|
||||
pub fn set_uncertainty(&mut self, uncertainty: Option<f64>) -> Result<(), Error> {
|
||||
if let Some(unc) = uncertainty {
|
||||
if unc < 0.0 {
|
||||
|
@ -413,59 +369,6 @@ impl GeoUri {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Validates the coordinates.
|
||||
///
|
||||
/// This is only meant for internal use to prevent returning [`GeoUri`] objects that are
|
||||
/// actually invalid.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the current latitude/longitude is invalid with respect to the current
|
||||
/// coordinate reference system, or if the uncertainy, if set, is not zero or positive.
|
||||
fn validate(&self) -> Result<(), Error> {
|
||||
// Validate the latitude/longitude against the coordinate refrence system.
|
||||
self.crs.validate(self.latitude, self.longitude)?;
|
||||
|
||||
// Ensure that the uncertainty is not negatify, if set.
|
||||
if let Some(unc) = self.uncertainty {
|
||||
if unc < 0.0 {
|
||||
return Err(Error::OutOfRangeUncertainty);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
struct GeoUriVisitor;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'de> Visitor<'de> for GeoUriVisitor {
|
||||
type Value = GeoUri;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(formatter, "a string starting with {URI_SCHEME_NAME}:")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
GeoUri::parse(v).map_err(E::custom)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
|
||||
impl<'de> Deserialize<'de> for GeoUri {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_str(GeoUriVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for GeoUri {
|
||||
|
@ -490,22 +393,6 @@ impl fmt::Display for GeoUri {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "url")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "url")))]
|
||||
impl From<&GeoUri> for Url {
|
||||
fn from(geo_uri: &GeoUri) -> Self {
|
||||
Url::parse(&geo_uri.to_string()).expect("valid URL")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "url")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "url")))]
|
||||
impl From<GeoUri> for Url {
|
||||
fn from(geo_uri: GeoUri) -> Self {
|
||||
Url::from(&geo_uri)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for GeoUri {
|
||||
type Err = Error;
|
||||
|
||||
|
@ -514,17 +401,6 @@ impl FromStr for GeoUri {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
|
||||
impl Serialize for GeoUri {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
serializer.serialize_str(&self.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for GeoUri {
|
||||
type Error = Error;
|
||||
|
||||
|
@ -533,57 +409,6 @@ impl TryFrom<&str> for GeoUri {
|
|||
}
|
||||
}
|
||||
|
||||
impl TryFrom<(f64, f64)> for GeoUri {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from((latitude, longitude): (f64, f64)) -> Result<Self, Self::Error> {
|
||||
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<Self, Self::Error> {
|
||||
let geo_uri = GeoUri {
|
||||
latitude,
|
||||
longitude,
|
||||
altitude: Some(altitude),
|
||||
..Default::default()
|
||||
};
|
||||
geo_uri.validate()?;
|
||||
|
||||
Ok(geo_uri)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "url")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "url")))]
|
||||
impl TryFrom<&Url> for GeoUri {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(url: &Url) -> Result<Self, Self::Error> {
|
||||
GeoUri::parse(url.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "url")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "url")))]
|
||||
impl TryFrom<Url> for GeoUri {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(url: Url) -> Result<Self, Self::Error> {
|
||||
GeoUri::try_from(&url)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for GeoUri {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
// In the WGS-84 CRS the the longitude is ignored for the poles.
|
||||
|
@ -599,10 +424,6 @@ impl PartialEq for GeoUri {
|
|||
|
||||
impl GeoUriBuilder {
|
||||
/// Validates the coordinates against the
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the the currently configured coordinate values are invalid.
|
||||
fn validate(&self) -> Result<(), String> {
|
||||
self.crs
|
||||
.unwrap_or_default()
|
||||
|
@ -625,8 +446,6 @@ impl GeoUriBuilder {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use float_eq::assert_float_eq;
|
||||
#[cfg(feature = "serde")]
|
||||
use serde_test::{assert_de_tokens_error, assert_tokens, Token};
|
||||
|
||||
use super::*;
|
||||
|
||||
|
@ -679,12 +498,6 @@ mod tests {
|
|||
Err(GeoUriBuilderError::ValidationError(_))
|
||||
));
|
||||
|
||||
builder.longitude(5.134).uncertainty(-200.0);
|
||||
assert!(matches!(
|
||||
builder.build(),
|
||||
Err(GeoUriBuilderError::ValidationError(_))
|
||||
));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -797,29 +610,6 @@ mod tests {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn geo_uri_validate() {
|
||||
let mut geo_uri = GeoUri {
|
||||
crs: CoordRefSystem::Wgs84,
|
||||
latitude: 52.107,
|
||||
longitude: 5.134,
|
||||
altitude: None,
|
||||
uncertainty: None,
|
||||
};
|
||||
assert_eq!(geo_uri.validate(), Ok(()));
|
||||
|
||||
geo_uri.latitude = 100.0;
|
||||
assert_eq!(geo_uri.validate(), Err(Error::OutOfRangeLatitude));
|
||||
|
||||
geo_uri.latitude = 52.107;
|
||||
geo_uri.longitude = -200.0;
|
||||
assert_eq!(geo_uri.validate(), Err(Error::OutOfRangeLongitude));
|
||||
|
||||
geo_uri.longitude = 5.134;
|
||||
geo_uri.uncertainty = Some(-2000.0);
|
||||
assert_eq!(geo_uri.validate(), Err(Error::OutOfRangeUncertainty));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn geo_uri_get_set() {
|
||||
let mut geo_uri = GeoUri {
|
||||
|
@ -874,25 +664,6 @@ mod tests {
|
|||
assert_eq!(&geo_uri.to_string(), "geo:52.107,5.134,3.6;u=25000");
|
||||
}
|
||||
|
||||
#[cfg(feature = "url")]
|
||||
#[test]
|
||||
fn geo_uri_from() {
|
||||
let geo_uri = GeoUri {
|
||||
crs: CoordRefSystem::Wgs84,
|
||||
latitude: 52.107,
|
||||
longitude: 5.134,
|
||||
altitude: Some(3.6),
|
||||
uncertainty: Some(1000.0),
|
||||
};
|
||||
let url = Url::from(&geo_uri);
|
||||
assert_eq!(url.scheme(), "geo");
|
||||
assert_eq!(url.path(), "52.107,5.134,3.6;u=1000");
|
||||
|
||||
let url = Url::from(geo_uri);
|
||||
assert_eq!(url.scheme(), "geo");
|
||||
assert_eq!(url.path(), "52.107,5.134,3.6;u=1000");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn geo_uri_from_str() -> Result<(), Error> {
|
||||
let geo_uri = GeoUri::from_str("geo:52.107,5.134")?;
|
||||
|
@ -904,89 +675,14 @@ mod tests {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn geo_uri_serde() {
|
||||
let geo_uri = GeoUri {
|
||||
crs: CoordRefSystem::Wgs84,
|
||||
latitude: 52.107,
|
||||
longitude: 5.134,
|
||||
altitude: Some(3.6),
|
||||
uncertainty: Some(1000.0),
|
||||
};
|
||||
assert_tokens(&geo_uri, &[Token::String("geo:52.107,5.134,3.6;u=1000")]);
|
||||
|
||||
assert_de_tokens_error::<GeoUri>(
|
||||
&[Token::I32(0)],
|
||||
"invalid type: integer `0`, expected a string starting with geo:",
|
||||
);
|
||||
assert_de_tokens_error::<GeoUri>(
|
||||
&[Token::String("geo:100.0,5.134,3.6")],
|
||||
&format!("{}", Error::OutOfRangeLatitude),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn geo_uri_try_from() -> Result<(), Error> {
|
||||
// &str
|
||||
let geo_uri = GeoUri::try_from("geo:52.107,5.134")?;
|
||||
assert_float_eq!(geo_uri.latitude, 52.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);
|
||||
|
||||
// (f64, f64)
|
||||
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)
|
||||
);
|
||||
|
||||
// (f64, f64, f64)
|
||||
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(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "url")]
|
||||
#[test]
|
||||
fn geo_uri_try_from_url() -> Result<(), Error> {
|
||||
// Url
|
||||
let url = Url::parse("geo:51.107,5.134,3.6;crs=wgs84;u=1000;foo=bar").expect("valid URL");
|
||||
let geo_uri = GeoUri::try_from(&url)?;
|
||||
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, Some(1000.0));
|
||||
|
||||
let geo_uri = GeoUri::try_from(url)?;
|
||||
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, Some(1000.0));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue