use crate::haystack::val::Value;
use std::{
cmp::Ordering,
convert::{From, TryFrom},
hash::Hash,
};
#[derive(Copy, Clone, Debug, Default)]
pub struct Coord {
pub lat: f64,
pub long: f64,
}
impl Coord {
pub fn make(lat: f64, long: f64) -> Coord {
Coord { lat, long }
}
}
impl From<Coord> for Value {
fn from(value: Coord) -> Self {
Value::Coord(value)
}
}
impl TryFrom<&Value> for Coord {
type Error = &'static str;
fn try_from(value: &Value) -> Result<Self, Self::Error> {
match value {
Value::Coord(v) => Ok(*v),
_ => Err("Value is not an `Coord`"),
}
}
}
impl Hash for Coord {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.lat.to_bits().hash(state);
self.long.to_bits().hash(state);
}
}
impl PartialEq for Coord {
fn eq(&self, other: &Self) -> bool {
self.lat.eq(&other.lat) && self.long.eq(&other.long)
}
}
impl Eq for Coord {}
#[allow(clippy::non_canonical_partial_ord_impl)]
impl PartialOrd for Coord {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.lat.partial_cmp(&other.lat).and_then(|ord| {
if ord == Ordering::Equal {
self.long.partial_cmp(&other.long)
} else {
Some(ord)
}
})
}
}
impl Ord for Coord {
fn cmp(&self, other: &Self) -> Ordering {
if self.lat < other.lat {
Ordering::Less
} else if self.lat > other.lat {
Ordering::Greater
} else if self.long < other.long {
Ordering::Less
} else if self.long > other.long {
Ordering::Greater
} else {
Ordering::Equal
}
}
}