use crate::directions::error::Error as DirectionsError;
use crate::error::Error as GoogleMapsError;
use chrono::DateTime;
use chrono::NaiveDateTime;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize, Deserialize)]
#[repr(u8)]
pub enum DepartureTime {
#[default]
Now = 0,
At(NaiveDateTime) = 1,
}
impl std::convert::From<&DepartureTime> for String {
fn from(departure_time: &DepartureTime) -> Self {
match departure_time {
DepartureTime::Now => Self::from("now"),
DepartureTime::At(departure_time) => departure_time.and_utc().timestamp().to_string(),
} } }
impl std::fmt::Display for DepartureTime {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{departure_time}", departure_time = String::from(self))
} }
impl std::convert::TryFrom<&str> for DepartureTime {
type Error = GoogleMapsError;
fn try_from(departure_time: &str) -> Result<Self, Self::Error> {
if departure_time == "now" {
Ok(Self::Now)
} else {
match departure_time.parse::<i64>() {
Ok(integer) => match DateTime::from_timestamp(integer, 0) {
Some(date_time) => Ok(Self::At(date_time.naive_utc())),
None => Err(DirectionsError::InvalidDepartureTime(
departure_time.to_string(),
))?,
}, Err(_error) => Err(DirectionsError::InvalidDepartureTime(
departure_time.to_string(),
))?,
} } } }
impl std::str::FromStr for DepartureTime {
type Err = GoogleMapsError;
fn from_str(departure_time: &str) -> Result<Self, Self::Err> {
Self::try_from(departure_time)
} }
impl DepartureTime {
#[must_use]
pub fn display(&self) -> String {
match self {
Self::Now => "Now".to_string(),
Self::At(departure_time) => {
format!("At {}", departure_time.format("At %F %r"))
}
} } }