use serde::{Deserialize, Serialize};
const MVG_LOCATION: &str = "https://www.mvg.de/api/fib/v2/location";
const MVG_STATION_NEARBY: &str = "https://www.mvg.de/api/fib/v2/station/nearby";
const MVG_DEPARTURE: &str = "https://www.mvg.de/api/fib/v2/departure";
const MVG_STATIONS: &str = "https://www.mvg.de/.rest/zdm/stations";
const MVG_STATION_GLOBAL_IDS: &str = "https://www.mvg.de/.rest/zdm/mvgStationGlobalIds";
const MVG_LINES: &str = "https://www.mvg.de/.rest/zdm/lines";
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Station {
pub abbreviation: Option<String>,
pub diva_id: Option<u32>,
pub id: Option<String>,
pub latitude: Option<f32>,
pub longitude: Option<f32>,
pub name: Option<String>,
pub place: Option<String>,
pub products: Option<Vec<String>>,
pub tariff_zones: Option<String>,
}
pub async fn stations() -> Result<Vec<Station>, Box<dyn std::error::Error>> {
let resp = reqwest::get(MVG_STATIONS).await?;
let stations = resp.json::<Vec<Station>>().await?;
Ok(stations)
}
type StationGlobalId = String;
pub async fn station_global_ids() -> Result<Vec<StationGlobalId>, Box<dyn std::error::Error>> {
let resp = reqwest::get(MVG_STATION_GLOBAL_IDS).await?;
let ids = resp.json::<Vec<StationGlobalId>>().await?;
Ok(ids)
}
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Line {
pub line_number: Option<i32>,
pub name: Option<String>,
pub product: Option<String>,
}
pub async fn lines() -> Result<Vec<Line>, Box<dyn std::error::Error>> {
let resp = reqwest::get(MVG_LINES).await?;
let lines = resp.json::<Vec<Line>>().await?;
Ok(lines)
}
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct DepartureInfo {
pub banner_hash: Option<String>,
pub cancelled: Option<bool>,
pub delay_in_minutes: Option<i32>, pub destination: Option<String>,
pub diva_id: Option<String>,
pub label: Option<String>,
pub messages: Option<Vec<String>>,
pub network: Option<String>,
pub occupancy: Option<String>,
pub planned_departure_time: Option<i64>, pub platform: Option<u32>,
pub platform_changed: Option<bool>,
pub realtime: Option<bool>,
pub realtime_departure_time: Option<i64>, pub sev: Option<bool>,
pub stop_point_global_id: Option<String>,
pub stop_position_number: Option<u32>,
pub train_type: Option<String>,
pub transport_type: Option<String>,
}
pub async fn departures<S: Into<String>>(
global_id: S,
) -> Result<Vec<DepartureInfo>, Box<dyn std::error::Error>> {
let url = format!("{}?globalId={}", MVG_DEPARTURE, global_id.into());
let resp = reqwest::get(url).await?;
let departures = resp.json::<Vec<DepartureInfo>>().await?;
Ok(departures)
}
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Location {
pub aliases: Option<String>,
pub distance_in_meters: Option<i32>,
pub diva_id: Option<u32>,
pub global_id: Option<String>,
pub has_zoom_data: Option<bool>,
pub latitude: Option<f32>,
pub longitude: Option<f32>,
pub name: Option<String>,
pub place: Option<String>,
pub surrounding_plan_link: Option<String>,
pub tariff_zones: Option<String>,
pub transport_types: Option<Vec<String>>,
pub r#type: Option<String>,
}
pub async fn locations<S: Into<String>>(
query: S,
) -> Result<Vec<Location>, Box<dyn std::error::Error>> {
let url = format!("{}?query={}", MVG_LOCATION, query.into());
let resp = reqwest::get(url).await?;
let locations = resp.json::<Vec<Location>>().await?;
Ok(locations)
}
pub async fn nearby_locations(
latitude: f32,
longitude: f32,
) -> Result<Vec<Location>, Box<dyn std::error::Error>> {
let url = format!(
"{}?latitude={}&longitude={}",
MVG_STATION_NEARBY, latitude, longitude
);
let resp = reqwest::get(url).await?;
let locations = resp.json::<Vec<Location>>().await?;
Ok(locations)
}
#[cfg(test)]
mod tests {
use super::*;
}