airlabs_client/
lib.rs

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;