1use super::Result;
2use reqwest::Method;
3use reqwest::header::{USER_AGENT, AUTHORIZATION};
4use crate::error::{Error, ErrorResponse};
5
6#[derive(Clone)]
7pub struct Client {
8 key: String,
9}
10
11impl Client {
12 pub fn new<S: AsRef<str>>(api: S) -> Client {
13 Client {
14 key: api.as_ref().to_string(),
15 }
16 }
17
18 pub async fn get<A, B>(&self, path: &str, param: Vec<&str>, data: B) -> Result<A>
19 where
20 A: serde::de::DeserializeOwned + Send + 'static,
21 B: serde::Serialize,
22 {
23 self.request(Method::GET, path, param, data).await
24 }
25
26 pub async fn post<A, B>(&self, path: &str, param: Vec<&str>, data: B) -> Result<A>
27 where
28 A: serde::de::DeserializeOwned + Send + 'static,
29 B: serde::Serialize,
30 {
31 self.request(Method::POST, path, param, data).await
32 }
33
34 pub async fn put<A, B>(&self, path: &str, param: Vec<&str>, data: B) -> Result<A>
35 where
36 A: serde::de::DeserializeOwned + Send + 'static,
37 B: serde::Serialize,
38 {
39 self.request(Method::PUT, path, param, data).await
40 }
41
42
43 pub async fn delete<A, B>(&self, path: &str, param: Vec<&str>, data: B) -> Result<A>
44 where
45 A: serde::de::DeserializeOwned + Send + 'static,
46 B: serde::Serialize,
47 {
48 self.request(Method::DELETE, path, param, data).await
49 }
50
51 pub async fn request<A, B>(
52 &self,
53 method: Method,
54 path: &str,
55 param: Vec<&str>,
56 data: B,
57 ) -> Result<A>
58 where
59 A: serde::de::DeserializeOwned + Send + 'static,
60 B: serde::Serialize,
61 {
62 let mut param = param
63 .iter()
64 .map(|s| s.to_string())
65 .collect::<Vec<String>>()
66 .join("/");
67
68
69 if param.len() > 0 {
70 param = format!("/{}", param);
71 }
72 let client = reqwest::Client::new();
73
74 let uri = format!("https://backend.mercury.com/api/v1{}{}", path, param);
75
76 let req = client
77 .request(method, &uri)
78 .json(&data)
79 .header(AUTHORIZATION, format!("Bearer {}", self.key.clone()))
80 .header(USER_AGENT, "mercury-client/rust");
81
82 let res = req.send().await?;
83
84 return if res.status().is_success() {
85 res.json().await.map_err(super::error::Error::from)
86 } else {
87 let res_body = res.json::<ErrorResponse>().await?;
88 Err(Error::MercuryError { errors: res_body.errors })
89 }
90
91 }
92}