summaryrefslogtreecommitdiff
path: root/src/types.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/types.rs')
-rw-r--r--src/types.rs260
1 files changed, 132 insertions, 128 deletions
diff --git a/src/types.rs b/src/types.rs
index f4947e2..22ba077 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -8,181 +8,185 @@ use crate::serde::*;
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Station {
- name: String,
- ds100: String,
- uic: u64,
- latitude: f64,
- longitude: f64,
- #[serde(deserialize_with = "naive_read_unixtime")]
- scheduled_time: DateTime<Utc>,
- #[serde(deserialize_with = "naive_read_unixtime")]
- real_time: DateTime<Utc>,
+ name: String,
+ ds100: String,
+ uic: u64,
+ latitude: f64,
+ longitude: f64,
+ #[serde(deserialize_with = "naive_read_unixtime")]
+ scheduled_time: DateTime<Utc>,
+ #[serde(deserialize_with = "naive_read_unixtime")]
+ real_time: DateTime<Utc>
}
pub fn parse_optional_station<'de, D>(d: D) -> Result<Option<Station>, D::Error>
where
- D: Deserializer<'de>,
+ D: Deserializer<'de>
{
- let val = <serde_json::Value>::deserialize(d)?;
- match serde_json::from_value(val) {
- Ok(station) => Ok(Some(station)),
- Err(_) => Ok(None),
- }
+ let val = <serde_json::Value>::deserialize(d)?;
+ 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<DateTime<Utc>>,
- #[serde(deserialize_with = "option_naive_read_unixtime")]
- real_arrival: Option<DateTime<Utc>>,
- #[serde(deserialize_with = "option_naive_read_unixtime")]
- scheduled_departure: Option<DateTime<Utc>>,
- #[serde(deserialize_with = "option_naive_read_unixtime")]
- real_departure: Option<DateTime<Utc>>,
+ name: String,
+ #[serde(deserialize_with = "option_naive_read_unixtime")]
+ scheduled_arrival: Option<DateTime<Utc>>,
+ #[serde(deserialize_with = "option_naive_read_unixtime")]
+ real_arrival: Option<DateTime<Utc>>,
+ #[serde(deserialize_with = "option_naive_read_unixtime")]
+ scheduled_departure: Option<DateTime<Utc>>,
+ #[serde(deserialize_with = "option_naive_read_unixtime")]
+ real_departure: Option<DateTime<Utc>>
}
pub trait IsStation {
- 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 {
- format!(
- "{} {} – {} ({})",
- 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,
- };
- let text = format!("({:+})", delay);
- if delay > 0 {
- text.red()
- } else {
- text.green()
- }
- },
- self.ds100().red(),
- self.name()
- )
- }
+ 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 {
+ format!(
+ "{} {} – {} ({})",
+ 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
+ };
+ let text = format!("({:+})", delay);
+ if delay > 0 {
+ text.red()
+ } else {
+ text.green()
+ }
+ },
+ self.ds100().red(),
+ self.name()
+ )
+ }
}
impl IsStation for Station {
- fn name(&self) -> &str {
- &self.name
- }
- fn scheduled_arrival(&self) -> Option<&DateTime<Utc>> {
- Some(&self.scheduled_time)
- }
- fn real_arrival(&self) -> Option<&DateTime<Utc>> {
- Some(&self.real_time)
- }
-
- fn ds100(&self) -> &str {
- &self.ds100
- }
+ fn name(&self) -> &str {
+ &self.name
+ }
+ fn scheduled_arrival(&self) -> Option<&DateTime<Utc>> {
+ Some(&self.scheduled_time)
+ }
+ fn real_arrival(&self) -> Option<&DateTime<Utc>> {
+ Some(&self.real_time)
+ }
+
+ fn ds100(&self) -> &str {
+ &self.ds100
+ }
}
impl IsStation for Stop {
- fn name(&self) -> &str {
- &self.name
- }
- fn scheduled_arrival(&self) -> Option<&DateTime<Utc>> {
- self.scheduled_arrival.as_ref()
- }
- fn real_arrival(&self) -> Option<&DateTime<Utc>> {
- self.real_arrival.as_ref()
- }
-
- fn ds100(&self) -> &str {
- "[??]"
- }
+ fn name(&self) -> &str {
+ &self.name
+ }
+ fn scheduled_arrival(&self) -> Option<&DateTime<Utc>> {
+ self.scheduled_arrival.as_ref()
+ }
+ fn real_arrival(&self) -> Option<&DateTime<Utc>> {
+ self.real_arrival.as_ref()
+ }
+
+ fn ds100(&self) -> &str {
+ "[??]"
+ }
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Train {
- #[serde(rename = "type")]
- _type: String,
- line: Option<String>,
- no: String,
- id: String,
+ #[serde(rename = "type")]
+ _type: String,
+ line: Option<String>,
+ no: String,
+ id: String
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Status {
- deprecated: bool,
- checked_in: bool,
- from_station: Station,
- #[serde(deserialize_with = "parse_optional_station")]
- pub to_station: Option<Station>,
- intermediate_stops: Vec<Stop>,
- train: Option<Train>,
- action_time: u64,
+ deprecated: bool,
+ checked_in: bool,
+ from_station: Station,
+ #[serde(deserialize_with = "parse_optional_station")]
+ pub to_station: Option<Station>,
+ intermediate_stops: Vec<Stop>,
+ train: Option<Train>,
+ action_time: u64
}
#[allow(dead_code)]
pub struct Ds100 {
- inner: String,
+ inner: String
}
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 {
- write!(f, "{} {}", self._type, self.no)
- }
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "{} {}", self._type, self.no)
+ }
}
#[allow(unstable_name_collisions)]
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());
- }
- Ok(())
+ 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());
}
+ Ok(())
+ }
}
impl std::fmt::Display for Status {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- match self.checked_in {
- false => write!(
- f,
- "not checked in. \n\n\
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self.checked_in {
+ false => write!(
+ f,
+ "not checked in. \n\n\
last trip: \n {} {}",
- self.from_station.to_fancy_string(),
- self.to_station.as_ref().unwrap().to_fancy_string()
- ),
- true => write!(
- f,
- "checked in to: {}.\n\n\
+ self.from_station.to_fancy_string(),
+ self.to_station.as_ref().unwrap().to_fancy_string()
+ ),
+ true => write!(
+ 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.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())
- ),
- }
+ 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())
+ )
}
+ }
}