1#![doc = include_str!("../LIBDOC.md")]
2
3#[macro_export]
5macro_rules! api_url {
6 ($e: expr) => {
7 concat!("http://datamall2.mytransport.sg/ltaodataservice", $e)
8 };
9}
10
11pub use crate::r#async::prelude::*;
12pub use crate::r#async::LTAClient;
13pub use lta_models as models;
14use reqwest::StatusCode;
15use thiserror::Error;
16
17pub mod prelude {
19 pub use crate::{Bus, Crowd, Facility, Geo, Taxi, Traffic, Train};
20}
21
22use crate::models::crowd::passenger_vol::VolType;
23pub use reqwest;
24
25pub mod r#async;
27
28#[cfg(feature = "blocking")]
30pub mod blocking;
31
32pub type LTAResult<T> = Result<T, LTAError>;
34
35#[derive(Error, Debug)]
37pub enum LTAError {
38 #[error("Internal error within the client backend, open a PR if this happens!")]
40 BackendError(#[from] reqwest::Error),
41
42 #[error("Invalid API Key!")]
44 InvalidAPIKey,
45
46 #[error("Server rate limit reached!")]
48 RateLimitReached,
49
50 #[error("Unknown enum variant!")]
52 UnknownEnumVariant,
53
54 #[error("HTTP Header Unauthorized")]
56 Unauthorized,
57
58 #[error("HTTP Header NotFound")]
60 NotFound,
61
62 #[error("Failed to parse body of response, probably malformed")]
64 FailedToParseBody,
65
66 #[error("Undocumented status code, open an issue if this happens")]
68 UnhandledStatusCode(StatusCode, String),
69
70 #[error("Custom error: `{0}`")]
72 Custom(String),
73}
74
75pub trait Client: Sized {
78 type InternalClient;
80
81 type RB;
83
84 fn new(api_key: impl Into<String>, client: Self::InternalClient) -> Self;
86
87 fn with_api_key(api_key: impl Into<String>) -> LTAResult<Self>;
90
91 fn req_builder(&self, url: &str) -> Self::RB;
93}
94
95#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
97pub struct Bus;
98
99#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
101pub struct Crowd;
102
103#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
105pub struct Taxi;
106
107#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
109pub struct Traffic;
110
111#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
113pub struct Train;
114
115#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
117pub struct Geo;
118
119#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
121pub struct Facility;
122
123pub(crate) const fn vol_type_to_url(vol_type: VolType) -> LTAResult<&'static str> {
125 use crate::models::crowd::passenger_vol;
126
127 let url = match vol_type {
128 VolType::BusStops => passenger_vol::URL_BY_BUS_STOPS,
129 VolType::OdBusStop => passenger_vol::URL_BY_OD_BUS_STOPS,
130 VolType::Train => passenger_vol::URL_BY_TRAIN,
131 VolType::OdTrain => passenger_vol::URL_BY_OD_TRAIN,
132 _ => return Err(LTAError::UnknownEnumVariant),
133 };
134
135 Ok(url)
136}