summaryrefslogtreecommitdiff
path: root/src/types.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/types.rs')
-rw-r--r--src/types.rs86
1 files changed, 41 insertions, 45 deletions
diff --git a/src/types.rs b/src/types.rs
index 2d8d189..2e4d2e1 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -1,6 +1,6 @@
use serde::{Deserialize, Deserializer};
-use chrono::NaiveDateTime;
+use chrono::{DateTime, Local, NaiveDateTime, Utc};
use colored::*;
use crate::serde::*;
@@ -14,55 +14,53 @@ pub struct Station {
latitude: f64,
longitude: f64,
#[serde(deserialize_with = "naive_read_unixtime")]
- scheduled_time: NaiveDateTime,
+ scheduled_time: DateTime<Utc>,
#[serde(deserialize_with = "naive_read_unixtime")]
- real_time: NaiveDateTime,
+ real_time: DateTime<Utc>,
}
-
pub fn parse_optional_station<'de, D>(d: D) -> Result<Option<Station>, D::Error>
where
D: Deserializer<'de>,
{
let val = <serde_json::Value>::deserialize(d)?;
- match serde_json::from_value(val) {
- Ok(station) => Ok(Some(station)),
- Err(_) => Ok(None)
- }
+ match serde_json::from_value(val) {
+ Ok(station) => Ok(Some(station)),
+ Err(_) => Ok(None),
+ }
}
-
-
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Stop {
name: String,
#[serde(deserialize_with = "option_naive_read_unixtime")]
- scheduled_arrival: Option<NaiveDateTime>,
+ scheduled_arrival: Option<DateTime<Utc>>,
#[serde(deserialize_with = "option_naive_read_unixtime")]
- real_arrival: Option<NaiveDateTime>,
+ real_arrival: Option<DateTime<Utc>>,
#[serde(deserialize_with = "option_naive_read_unixtime")]
- scheduled_departure: Option<NaiveDateTime>,
+ scheduled_departure: Option<DateTime<Utc>>,
#[serde(deserialize_with = "option_naive_read_unixtime")]
- real_departure: Option<NaiveDateTime>,
+ real_departure: Option<DateTime<Utc>>,
}
-
-
pub trait IsStation {
- fn name (&self) -> &str;
- fn scheduled_arrival (&self) -> Option<&NaiveDateTime>;
- fn real_arrival (&self) -> Option<&NaiveDateTime>;
- fn ds100 (&self) -> &str;
+ fn name(&self) -> &str;
+ fn scheduled_arrival(&self) -> Option<&DateTime<Utc>>;
+ fn real_arrival(&self) -> Option<&DateTime<Utc>>;
+ fn ds100(&self) -> &str;
- fn to_fancy_string (&self) -> String {
+ fn to_fancy_string(&self) -> String {
format!(
"{} {} – {} ({})",
- self.real_arrival().map(|t| t.time().to_string()).unwrap_or("??:??:??".to_string()).blue(),
+ self.real_arrival() // chrono's API for timezones is expressive, but reads like c++ …
+ .map(|t| <DateTime<Local>>::from(*t).time().to_string())
+ .unwrap_or("??:??:??".to_string())
+ .blue(),
{
let delay = match (self.real_arrival(), self.scheduled_arrival()) {
(Some(a), Some(s)) => (a.time() - s.time()).num_minutes(),
- _ => 0
+ _ => 0,
};
let text = format!("({:+})", delay);
if delay > 0 {
@@ -78,40 +76,37 @@ pub trait IsStation {
}
impl IsStation for Station {
- fn name (&self) -> &str {
+ fn name(&self) -> &str {
&self.name
}
- fn scheduled_arrival (&self) -> Option<&NaiveDateTime> {
+ fn scheduled_arrival(&self) -> Option<&DateTime<Utc>> {
Some(&self.scheduled_time)
}
- fn real_arrival (&self) -> Option<&NaiveDateTime> {
+ fn real_arrival(&self) -> Option<&DateTime<Utc>> {
Some(&self.real_time)
}
- fn ds100 (&self) -> &str {
+ fn ds100(&self) -> &str {
&self.ds100
}
}
impl IsStation for Stop {
- fn name (&self) -> &str {
+ fn name(&self) -> &str {
&self.name
}
- fn scheduled_arrival (&self) -> Option<&NaiveDateTime> {
+ fn scheduled_arrival(&self) -> Option<&DateTime<Utc>> {
self.scheduled_arrival.as_ref()
}
- fn real_arrival (&self) -> Option<&NaiveDateTime> {
+ fn real_arrival(&self) -> Option<&DateTime<Utc>> {
self.real_arrival.as_ref()
}
- fn ds100 (&self) -> &str {
+ fn ds100(&self) -> &str {
"[??]"
}
}
-
-
-
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Train {
@@ -122,8 +117,6 @@ pub struct Train {
id: String,
}
-
-
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Status {
@@ -142,8 +135,7 @@ pub struct Ds100 {
inner: String,
}
-pub struct Trip<'a, S: IsStation> (pub &'a Vec<S>);
-
+pub struct Trip<'a, S: IsStation>(pub &'a Vec<S>);
impl std::fmt::Display for Train {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
@@ -155,16 +147,16 @@ impl std::fmt::Display for Train {
impl<S: IsStation> std::fmt::Display for Trip<'_, S> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if self.0.len() != 0 {
- self.0.iter()
- .map(|stop| stop.to_fancy_string())
- // .intersperse(" ↓".to_string())
- .for_each(|l| writeln!(f, " {}\n ↓", l).unwrap());
+ self.0
+ .iter()
+ .map(|stop| stop.to_fancy_string())
+ // .intersperse(" ↓".to_string())
+ .for_each(|l| writeln!(f, " {}\n ↓", l).unwrap());
}
Ok(())
}
}
-
impl std::fmt::Display for Status {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self.checked_in {
@@ -179,14 +171,18 @@ impl std::fmt::Display for Status {
f,
"checked in to: {}.\n\n\
stops:\n {}\n ↓\n{} {}",
- self.train.as_ref().map(|t| t.to_string()).unwrap_or("".to_string()).green(),
+ self.train
+ .as_ref()
+ .map(|t| t.to_string())
+ .unwrap_or("".to_string())
+ .green(),
self.from_station.to_fancy_string(),
Trip(&self.intermediate_stops),
self.to_station
.as_ref()
.map(|s| s.to_fancy_string())
.unwrap_or_else(|| "🚄 Fahrt ins Blaue".blue().to_string())
- )
+ ),
}
}
}