termii_rust/async_impl/http/
client.rs

1use std::collections::HashMap;
2
3use reqwest::{Client, Method, Response, Url};
4use serde;
5
6use crate::common::errors::HttpError;
7
8#[derive(Debug)]
9pub struct HttpClient {
10    base_url: Url,
11    client: Client,
12    timeout: u64,
13}
14
15impl HttpClient {
16    pub fn new(timeout: u64) -> Result<HttpClient, HttpError> {
17        if timeout < 1 {
18            return Err(HttpError::InvalidTimeout(timeout));
19        }
20
21        let base_url = Url::parse("https://api.ng.termii.com/api/")
22            .map_err(|err| HttpError::UrlParseError(err.to_string()))?;
23
24        let client = Client::builder()
25            .timeout(std::time::Duration::from_secs(timeout))
26            .build()?;
27
28        Ok(HttpClient {
29            base_url: base_url,
30            client: client,
31            timeout: timeout,
32        })
33    }
34
35    async fn request<T>(
36        &self,
37        url: &str,
38        method: Method,
39        params: Option<HashMap<&str, &str>>,
40        _headers: Option<HashMap<&str, &str>>,
41        data: Option<T>,
42    ) -> Result<Response, HttpError>
43    where
44        T: serde::Serialize,
45    {
46        let timeout = Some(self.timeout);
47
48        let url = self
49            .base_url
50            .join(url)
51            .map_err(|err| HttpError::UrlParseError(err.to_string()))?;
52
53        let mut _client = self
54            .client
55            .request(method, url)
56            .timeout(std::time::Duration::from_millis(timeout.unwrap() * 1000));
57
58        if let Some(params) = params {
59            _client = _client.query(&params);
60        }
61
62        if let Some(data) = data {
63            _client = _client.json(&data);
64        }
65
66        let response = _client.send().await?;
67
68        Ok(response)
69    }
70
71    pub async fn get(
72        &self,
73        url: &str,
74        params: Option<HashMap<&str, &str>>,
75        headers: Option<HashMap<&str, &str>>,
76    ) -> Result<Response, HttpError> {
77        self.request(url, Method::GET, params, headers, None::<u8>)
78            .await
79    }
80
81    pub async fn post<T>(
82        &self,
83        url: &str,
84        params: Option<HashMap<&str, &str>>,
85        headers: Option<HashMap<&str, &str>>,
86        data: Option<T>,
87    ) -> Result<Response, HttpError>
88    where
89        T: serde::Serialize,
90    {
91        self.request(url, Method::POST, params, headers, data).await
92    }
93
94    pub async fn patch<T>(
95        &self,
96        url: &str,
97        params: Option<HashMap<&str, &str>>,
98        headers: Option<HashMap<&str, &str>>,
99        data: Option<T>,
100    ) -> Result<Response, HttpError>
101    where
102        T: serde::Serialize,
103    {
104        self.request(url, Method::PATCH, params, headers, data)
105            .await
106    }
107
108    pub async fn delete(
109        &self,
110        url: &str,
111        params: Option<HashMap<&str, &str>>,
112        headers: Option<HashMap<&str, &str>>,
113    ) -> Result<Response, HttpError> {
114        self.request(url, Method::DELETE, params, headers, None::<u8>)
115            .await
116    }
117}