#![allow(unused_parens)]
use std::str::FromStr;
pub mod error;
#[derive(Clone, Copy, Debug)]
pub struct Coordinates {
latitude: f64,
longitude: f64
}
impl FromStr for Coordinates {
type Err = error::ParseError;
fn from_str(input: &str) -> Result<Self, Self::Err> {
let parts: Vec<&str> = input.split(',').collect();
if(parts.len() != 2) {
return Err(error::ParseError::InvalidFormat(input.into()));
}
let latitude = parts[0].trim().parse()?;
let longitude = parts[1].trim().parse()?;
Ok(Coordinates::new(latitude, longitude)?)
}
}
impl Coordinates {
#[inline]
pub fn new(latitude: f64, longitude: f64) -> Result<Self, error::OutOfRange> {
let mut this = Self{
latitude: 0.0,
longitude: 0.0
};
this.set_latitude_degrees(latitude)?;
this.set_longitude_degrees(longitude)?;
Ok(this)
}
#[inline]
pub fn latitude_degrees(&self) -> f64 {
self.latitude
}
#[inline]
pub fn longitude_degrees(&self) -> f64 {
self.longitude
}
#[inline]
pub fn set_latitude_degrees(&mut self, latitude: f64) -> Result<(), error::LatitudeOutOfRange> {
if(!(-90.0..=90.0).contains(&latitude)) {
return Err(error::LatitudeOutOfRange(latitude));
}
self.latitude = latitude;
Ok(())
}
#[inline]
pub fn set_longitude_degrees(&mut self, longitude: f64) -> Result<(), error::LongitudeOutOfRange> {
if(!(-180.0..=180.0).contains(&longitude)) {
return Err(error::LongitudeOutOfRange(longitude));
}
self.longitude = longitude;
Ok(())
}
}