1use std::borrow::Borrow;
2use std::collections::HashMap;
3use reqwest::{Client, Response};
4use anyhow::Result;
5use serde_json::Value;
6use std::sync::atomic::AtomicBool;
7use serde::de::DeserializeOwned;
8use tokio::sync::Mutex;
9
10pub struct ApiClient {
11 pub(crate) apikey: String,
12 DEBUG_MODE: Mutex<AtomicBool>,
13}
14
15impl ApiClient {
16 pub fn new(apikey: &str) -> Self {
17 Self {
18 apikey: String::from(apikey),
19 DEBUG_MODE: Mutex::new(AtomicBool::new(false)),
20 }
21 }
22
23 pub async fn enable_debug_mode(self) -> Self {
29 let mut temp = self.DEBUG_MODE.lock().await;
30 *temp = AtomicBool::new(true);
31 drop(temp);
32 self
33 }
34
35 pub async fn is_debug_enabled(&self) -> bool {
36 *self.DEBUG_MODE.lock().await.get_mut()
37 }
38
39 pub async fn clone(&self) -> Self {
41 Self {
42 apikey: self.apikey.clone(),
43 DEBUG_MODE: Mutex::new(AtomicBool::new(self.is_debug_enabled().await)),
44 }
45 }
46
47 pub async fn get(&self, url: String) -> Result<String> {
48 self.get_params(url, HashMap::new()).await
49 }
50
51 pub async fn get_params(&self, url: String, map: HashMap<&str, &str>) -> Result<String> {
52 let client = reqwest::Client::new();
53 let resp = client
54 .get(url.clone())
55 .header("X-API-KEY", self.apikey.as_str())
56 .query(&map)
57 .send()
58 .await?;
59
60 let text = resp.text().await?;
61
62 if self.is_debug_enabled().await {
63 println!("GET {}", url);
64 println!("{}", text.clone());
65 }
66
67
68 Ok(text)
69 }
70
71 pub async fn get_parse<T: DeserializeOwned>(&self, url: String, dewrap: bool) -> Result<T> {
72 if dewrap {
73 let val = serde_json::from_str::<Value>(self.get(url.clone()).await?.as_str())?;
74
75 return Ok(serde_json::from_value::<T>(val["Response"].clone())?)
76 }
77
78 let text = self.get(url.clone()).await?;
79
80 let r = serde_json::from_str::<T>(text.as_str())?;
81
82 Ok(r)
83 }
84
85 pub async fn get_parse_params<T: DeserializeOwned>(&self, url: String, dewrap: bool, map: HashMap<&str, &str>) -> Result<T> {
86 if dewrap {
87 let val = serde_json::from_str::<Value>(self.get_params(url.clone(), map).await?.as_str())?;
88
89 return Ok(serde_json::from_value::<T>(val["Response"].clone())?)
90 }
91
92 let text = self.get_params(url, map).await?;
93
94 Ok(serde_json::from_str::<T>(text.as_str())?)
95 }
96
97 pub async fn post(&self, url: String, body: String) -> Result<String> {
98 self.post_params(url, body, HashMap::new()).await
99 }
100
101 pub async fn post_params(&self, url: String, body: String, map: HashMap<&str, &str>) -> Result<String> {
102 let client = Client::new();
103 let resp = client
104 .post(url.clone())
105 .body(body.clone())
106 .header("X-API-KEY", self.apikey.as_str())
107 .query(&map)
108 .send()
109 .await?;
110
111 let text = resp.text().await?;
112
113 if self.is_debug_enabled().await {
114 println!("POST {}", url);
115 println!("Body - {}", body);
116 println!("{}", text.clone());
117 }
118
119 Ok(text)
120 }
121
122 pub async fn post_parse<T: DeserializeOwned>(&self, url: String, body: String, dewrap: bool) -> Result<T> {
123 if dewrap {
124 let val = serde_json::from_str::<Value>(self.post(url, body).await?.as_str())?;
125
126 return Ok(serde_json::from_value::<T>(val["Response"].clone())?)
127 }
128
129 let text = self.post(url, body).await?;
130
131 let r = serde_json::from_str::<T>(text.as_str())?;
132
133 Ok(r)
134 }
135
136 pub async fn post_parse_params<T: DeserializeOwned>(&self, url: String, body: String, map: HashMap<&str, &str>, dewrap: bool) -> Result<T> {
137 if dewrap {
138 let val = serde_json::from_str::<Value>(self.post_params(url, body, map).await?.as_str())?;
139
140 return Ok(serde_json::from_value::<T>(val["Response"].clone())?)
141 }
142
143 let text = self.post_params(url, body, map).await?;
144
145 Ok(serde_json::from_str::<T>(text.as_str())?)
146 }
147}
148
149pub trait HandleValue {
150 fn handle(value: Value) -> Value;
151}
152
153fn encode_url(url: String) -> String {
154 url.replace(" ", "%20")
155}