1use std::time;
2
3use airlabs_api as api;
4use serde_json as json;
5
6pub use error::Error;
7pub use response::Response;
8pub use response::ResponseType;
9
10mod error;
11mod response;
12
13#[derive(Debug)]
14pub struct Client {
15 base: String,
16 client: reqwest::Client,
17 key: String,
18 free_account: bool,
19}
20
21impl Client {
22 pub fn new(key: impl ToString) -> Self {
23 let base = "https://airlabs.co/api/v9".to_string();
24 let key = key.to_string();
25 let client = reqwest::Client::new();
26 let free_account = false;
27 Self {
28 base,
29 client,
30 key,
31 free_account,
32 }
33 }
34
35 pub fn update_from_ping(self, ping: Response<api::PingRequest>) -> json::Result<Self> {
36 let free_account = ping.is_free()?;
37 Ok(Self {
38 free_account,
39 ..self
40 })
41 }
42
43 pub fn is_free(&self) -> bool {
44 self.free_account
45 }
46
47 pub fn ping(&self) -> api::PingRequest {
48 api::PingRequest::new(&self.key)
49 }
50
51 pub fn airlines(&self) -> api::AirlinesRequest {
52 api::AirlinesRequest::new(&self.key)
53 }
54
55 pub fn airports(&self) -> api::AirportsRequest {
56 api::AirportsRequest::new(&self.key)
57 }
58
59 pub fn flight_iata(&self, code: impl ToString) -> api::FlightRequest {
60 api::FlightRequest::iata(&self.key, code)
61 }
62
63 pub fn flight_icao(&self, code: impl ToString) -> api::FlightRequest {
64 api::FlightRequest::icao(&self.key, code)
65 }
66
67 pub async fn send_ping(&self) -> reqwest::Result<Response<api::PingRequest>> {
68 let request = self.ping();
69 self.post(request).await
70 }
71
72 pub async fn get<R>(&self, request: R) -> reqwest::Result<Response<R>>
73 where
74 R: api::AirLabsRequest,
75 {
76 let start = time::Instant::now();
77 self.get_request(request)
78 .send()
79 .await?
80 .error_for_status()?
81 .text()
82 .await
83 .map(|raw| Response::new(raw, start.elapsed()))
84 }
85
86 pub async fn post<R>(&self, request: R) -> reqwest::Result<Response<R>>
87 where
88 R: api::AirLabsRequest,
89 {
90 let start = time::Instant::now();
91 self.post_request(request)
92 .send()
93 .await?
94 .error_for_status()?
95 .text()
96 .await
97 .map(|raw| Response::new(raw, start.elapsed()))
98 }
99
100 pub fn get_request<R>(&self, request: R) -> reqwest::RequestBuilder
101 where
102 R: api::AirLabsRequest,
103 {
104 let url = self.url(&request);
105 self.client.get(url).query(&request)
106 }
107
108 fn post_request<R>(&self, request: R) -> reqwest::RequestBuilder
109 where
110 R: api::AirLabsRequest,
111 {
112 let url = self.url(&request);
113 self.client.post(url).json(&request)
114 }
115
116 fn url<T>(&self, request: &T) -> String
117 where
118 T: api::AirLabsRequest,
119 {
120 request.url(&self.base)
121 }
122}
123
124#[cfg(test)]
125mod tests;