use crate::lta_client::LTAClient;
use crate::utils::commons::{build_req, build_res_with_query, Result};
pub mod bus_arrival {
use chrono::prelude::*;
use serde::{Deserialize, Serialize};
use crate::bus_enums::{BusFeature, BusLoad, BusType, Operator};
use crate::utils::de::from_str;
pub const URL: &str = "http://datamall2.mytransport.sg/ltaodataservice/BusArrivalv2";
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "PascalCase")]
pub struct ArrivalBusService {
pub service_no: String,
pub operator: Operator,
pub next_bus: NextBus,
pub next_bus_2: NextBus,
pub next_bus_3: NextBus,
}
impl ArrivalBusService {
pub fn next_bus_as_arr(&self) -> [&NextBus; 3] {
[&self.next_bus, &self.next_bus_2, &self.next_bus_3]
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Deserialize, Serialize)]
#[serde(rename_all = "PascalCase")]
pub struct NextBus {
#[serde(deserialize_with = "from_str")]
pub origin_code: u32,
#[serde(deserialize_with = "from_str", rename = "DestinationCode")]
pub dest_code: u32,
#[serde(rename = "EstimatedArrival")]
pub est_arrival: DateTime<FixedOffset>,
#[serde(deserialize_with = "from_str", rename = "Latitude")]
pub lat: f64,
#[serde(deserialize_with = "from_str", rename = "Longitude")]
pub long: f64,
#[serde(deserialize_with = "from_str", rename = "VisitNumber")]
pub visit_no: u32,
pub load: BusLoad,
pub feature: Option<BusFeature>,
#[serde(rename = "Type")]
pub bus_type: BusType,
}
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "PascalCase")]
pub struct BusArrivalResp {
#[serde(deserialize_with = "from_str")]
pub bus_stop_code: u32,
pub services: Vec<ArrivalBusService>,
}
}
pub fn get_arrival(
client: <AClient,
bus_stop_code: u32,
service_no: &str,
) -> Result<bus_arrival::BusArrivalResp> {
let resp: bus_arrival::BusArrivalResp =
build_res_with_query(client, bus_arrival::URL, |req_builder| {
req_builder.query(&[
("BusStopCode", bus_stop_code.to_string()),
("ServiceNo", service_no.to_string()),
])
})?;
Ok(resp)
}
pub mod bus_services {
use serde::{Deserialize, Serialize};
use crate::bus_enums::{BusCategory, Operator};
use crate::utils::de::{from_str, from_str_to_bus_freq};
pub const URL: &str = "http://datamall2.mytransport.sg/ltaodataservice/BusServices";
#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct BusFreq {
pub min: Option<u32>,
pub max: Option<u32>,
}
impl BusFreq {
pub fn new(min: u32, max: u32) -> Self {
BusFreq {
min: Some(min),
max: Some(max),
}
}
pub fn default() -> Self {
BusFreq::new(0, 0)
}
pub fn no_max(min: u32) -> Self {
BusFreq {
min: Some(min),
max: None,
}
}
pub fn no_timing() -> Self {
BusFreq {
min: None,
max: None,
}
}
}
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "PascalCase")]
pub struct BusService {
pub service_no: String,
pub operator: Operator,
#[serde(rename = "Direction")]
pub no_direction: u32,
pub category: BusCategory,
#[serde(deserialize_with = "from_str")]
pub origin_code: u32,
#[serde(deserialize_with = "from_str", rename = "DestinationCode")]
pub dest_code: u32,
#[serde(rename = "AM_Peak_Freq", deserialize_with = "from_str_to_bus_freq")]
pub am_peak_freq: BusFreq,
#[serde(rename = "AM_Offpeak_Freq", deserialize_with = "from_str_to_bus_freq")]
pub am_offpeak_freq: BusFreq,
#[serde(rename = "PM_Peak_Freq", deserialize_with = "from_str_to_bus_freq")]
pub pm_peak_freq: BusFreq,
#[serde(rename = "PM_Offpeak_Freq", deserialize_with = "from_str_to_bus_freq")]
pub pm_offpeak_freq: BusFreq,
pub loop_desc: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct BusServiceResp {
pub value: Vec<BusService>,
}
}
pub fn get_bus_services(client: <AClient) -> Result<Vec<bus_services::BusService>> {
let resp: bus_services::BusServiceResp = build_req(client, bus_services::URL)?;
Ok(resp.value)
}
pub mod bus_routes {
use chrono::prelude::*;
use serde::{Deserialize, Serialize};
use crate::bus_enums::Operator;
use crate::utils::de::{from_str, from_str_to_time};
use crate::utils::ser::from_time_to_str;
pub const URL: &str = "http://datamall2.mytransport.sg/ltaodataservice/BusRoutes";
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "PascalCase")]
pub struct BusRoute {
pub service_no: String,
pub operator: Operator,
pub direction: u32,
#[serde(rename = "StopSequence")]
pub stop_seq: u32,
#[serde(deserialize_with = "from_str")]
pub bus_stop_code: u32,
#[serde(rename = "Distance")]
pub dist: f64,
#[serde(
rename = "WD_FirstBus",
deserialize_with = "from_str_to_time",
serialize_with = "from_time_to_str"
)]
pub wd_first: Option<NaiveTime>,
#[serde(
rename = "WD_LastBus",
deserialize_with = "from_str_to_time",
serialize_with = "from_time_to_str"
)]
pub wd_last: Option<NaiveTime>,
#[serde(
rename = "SAT_FirstBus",
deserialize_with = "from_str_to_time",
serialize_with = "from_time_to_str"
)]
pub sat_first: Option<NaiveTime>,
#[serde(
rename = "SAT_LastBus",
deserialize_with = "from_str_to_time",
serialize_with = "from_time_to_str"
)]
pub sat_last: Option<NaiveTime>,
#[serde(
rename = "SUN_FirstBus",
deserialize_with = "from_str_to_time",
serialize_with = "from_time_to_str"
)]
pub sun_first: Option<NaiveTime>,
#[serde(
rename = "SUN_LastBus",
deserialize_with = "from_str_to_time",
serialize_with = "from_time_to_str"
)]
pub sun_last: Option<NaiveTime>,
}
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct BusRouteResp {
pub value: Vec<BusRoute>,
}
}
pub fn get_bus_routes(client: <AClient) -> Result<Vec<bus_routes::BusRoute>> {
let resp: bus_routes::BusRouteResp = build_req(client, bus_routes::URL)?;
Ok(resp.value)
}
pub mod bus_stops {
use serde::{Deserialize, Serialize};
use crate::utils::commons::Coordinates;
use crate::utils::de::from_str;
pub const URL: &str = "http://datamall2.mytransport.sg/ltaodataservice/BusStops";
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "PascalCase")]
pub struct BusStop {
#[serde(deserialize_with = "from_str")]
pub bus_stop_code: u32,
pub road_name: String,
#[serde(rename = "Description")]
pub desc: String,
#[serde(rename = "Latitude")]
pub lat: f64,
#[serde(rename = "Longitude")]
pub long: f64,
}
impl BusStop {
pub fn coordinates(&self) -> Coordinates {
Coordinates::new(self.lat, self.long)
}
}
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct BusStopsResp {
pub value: Vec<BusStop>,
}
}
pub fn get_bus_stops(client: <AClient) -> Result<Vec<bus_stops::BusStop>> {
let resp: bus_stops::BusStopsResp = build_req(client, bus_stops::URL)?;
Ok(resp.value)
}