use std::borrow::Cow; use chrono::DateTime; use chrono::Duration; use chrono::FixedOffset; #[cfg(feature = "polylines")] use geojson::FeatureCollection; use serde::{Deserialize, Serialize}; /* Types */ #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] pub enum Location { Address { address: String, latitude: f32, longitude: f32, }, Point { #[serde(skip_serializing_if = "Option::is_none")] id: Option, #[serde(skip_serializing_if = "Option::is_none")] name: Option, #[serde(skip_serializing_if = "Option::is_none")] poi: Option, latitude: f32, longitude: f32, }, } impl PartialEq for Location { fn eq(&self, other: &Self) -> bool { match (&self, other) { (Location::Address { address: a, .. }, Location::Address { address: b, .. }) => { a == b } (Location::Point { id: Some(a), .. }, Location::Point { id: Some(b), .. }) => { a == b } (_, _) => false, } } } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] #[serde(tag = "type")] #[serde(rename_all = "lowercase")] pub enum Place { Stop(Stop), Location(Location), } /*#[derive(Debug, Clone, Serialize)] pub struct Station { pub id: u64, pub name: String, pub coordinates: Coordinates, pub products: Products, }*/ #[derive(Debug, Default, Clone, Serialize, Deserialize)] pub struct Stop { pub id: String, #[serde(skip_serializing_if = "Option::is_none")] pub name: Option, pub location: Option, #[serde(skip_serializing_if = "Option::is_none")] pub products: Option>, //station: Option, } impl PartialEq for Stop { fn eq(&self, other: &Self) -> bool { self.id == other.id } } // None means true // TODO: What to do with the new products for other providers? #[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct ProductsSelection { pub national_express: Option, pub national: Option, pub regional_exp: Option, pub regional: Option, pub suburban: Option, pub bus: Option, pub ferry: Option, pub subway: Option, pub tram: Option, pub taxi: Option, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct Product { pub id: Cow<'static, str>, pub mode: Mode, pub bitmasks: Cow<'static, [u16]>, pub name: Cow<'static, str>, pub short: Cow<'static, str>, // TODO: default? } #[derive(Serialize, Debug, Clone, Deserialize, PartialEq, Eq)] #[serde(rename_all = "lowercase")] pub enum Mode { Train, Bus, Watercraft, Taxi, Walking, Gondola, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub enum LoyaltyCard { BahnCard25Class1, BahnCard25Class2, BahnCard50Class1, BahnCard50Class2, Vorteilscard, HalbtaxaboRailplus, Halbtaxabo, VoordeelurenaboRailplus, Voordeelurenabo, SHCard, Generalabonnement, } impl LoyaltyCard { /// See https://gist.github.com/juliuste/202bb04f450a79f8fa12a2ec3abcd72d pub fn from_id(value: u8) -> Option { match value { 1 => Some(LoyaltyCard::BahnCard25Class1), 2 => Some(LoyaltyCard::BahnCard25Class2), 3 => Some(LoyaltyCard::BahnCard50Class1), 4 => Some(LoyaltyCard::BahnCard50Class2), 9 => Some(LoyaltyCard::Vorteilscard), 10 => Some(LoyaltyCard::HalbtaxaboRailplus), 11 => Some(LoyaltyCard::Halbtaxabo), 12 => Some(LoyaltyCard::VoordeelurenaboRailplus), 13 => Some(LoyaltyCard::Voordeelurenabo), 14 => Some(LoyaltyCard::SHCard), 15 => Some(LoyaltyCard::Generalabonnement), _ => None, } } pub fn to_id(self) -> u8 { match self { LoyaltyCard::BahnCard25Class1 => 1, LoyaltyCard::BahnCard25Class2 => 2, LoyaltyCard::BahnCard50Class1 => 3, LoyaltyCard::BahnCard50Class2 => 4, LoyaltyCard::Vorteilscard => 9, LoyaltyCard::HalbtaxaboRailplus => 10, LoyaltyCard::Halbtaxabo => 11, LoyaltyCard::VoordeelurenaboRailplus => 12, LoyaltyCard::Voordeelurenabo => 13, LoyaltyCard::SHCard => 14, LoyaltyCard::Generalabonnement => 15, } } } #[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)] pub enum TariffClass { First, Second, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "lowercase")] pub enum Accessibility { r#None, Partial, Complete, } #[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "kebab-case")] pub enum LoadFactor { LowToMedium, High, VeryHigh, ExceptionallyHigh, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct Line { pub name: Option, pub fahrt_nr: Option, pub mode: Mode, pub product: Product, pub operator: Option, pub product_name: Option, } #[derive(Debug, Serialize, Clone, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct Frequency { #[serde(with = "crate::serialize::duration")] pub minimum: Option, #[serde(with = "crate::serialize::duration")] pub maximum: Option, pub iterations: Option, } #[derive(Debug, Serialize, Clone, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct Leg { pub origin: Place, pub destination: Place, pub departure: Option>, pub planned_departure: Option>, pub departure_delay: Option, pub arrival: Option>, pub planned_arrival: Option>, pub arrival_delay: Option, #[serde(skip_serializing_if = "Option::is_none")] pub reachable: Option, pub trip_id: Option, pub line: Option, pub direction: Option, //current_location, pub arrival_platform: Option, pub planned_arrival_platform: Option, pub departure_platform: Option, pub planned_departure_platform: Option, pub frequency: Option, #[serde(skip_serializing_if = "Option::is_none")] pub cancelled: Option, #[serde(skip_serializing_if = "Option::is_none")] pub stopovers: Option>, #[serde(skip_serializing_if = "Option::is_none")] pub load_factor: Option, #[serde(skip_serializing_if = "Option::is_none")] pub remarks: Option>, #[cfg(feature = "polylines")] #[serde(skip_serializing_if = "Option::is_none")] pub polyline: Option, #[serde(skip_serializing_if = "Option::is_none")] pub walking: Option, #[serde(skip_serializing_if = "Option::is_none")] pub transfer: Option, #[serde(skip_serializing_if = "Option::is_none")] pub distance: Option, } #[derive(Debug, Serialize, Clone, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct Stopover { pub stop: Place, pub departure: Option>, pub planned_departure: Option>, pub departure_delay: Option, pub arrival: Option>, pub planned_arrival: Option>, pub arrival_delay: Option, pub arrival_platform: Option, pub planned_arrival_platform: Option, pub departure_platform: Option, pub planned_departure_platform: Option, #[serde(skip_serializing_if = "Option::is_none")] pub cancelled: Option, #[serde(skip_serializing_if = "Option::is_none")] pub remarks: Option>, } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] pub struct Price { pub amount: f64, pub currency: String, } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[serde(rename_all = "camelCase")] pub struct Journey { #[serde(skip_serializing_if = "Option::is_none")] pub refresh_token: Option, pub legs: Vec, pub price: Option, //last_updated } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct Operator { pub id: String, pub name: String, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "lowercase")] pub enum RemarkType { Hint, Status, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct Remark { pub code: String, pub text: String, pub r#type: RemarkType, #[serde(skip_serializing_if = "Option::is_none")] pub summary: Option, #[serde(skip_serializing_if = "Option::is_none")] pub trip_id: Option, }