dex_connector/
dex_request.rs1use debot_utils::ParseDecimalError;
2use reqwest::{
3 header::{HeaderMap, HeaderValue},
4 Client, Method,
5};
6use serde::Serialize;
7use std::{
8 collections::HashMap,
9 error::Error as StdError,
10 fmt::{self, Display},
11};
12
13pub enum HttpMethod {
14 Get,
15 Post,
16 Put,
17 Delete,
18}
19
20impl From<HttpMethod> for Method {
21 fn from(method: HttpMethod) -> Self {
22 match method {
23 HttpMethod::Get => Method::GET,
24 HttpMethod::Post => Method::POST,
25 HttpMethod::Put => Method::PUT,
26 HttpMethod::Delete => Method::DELETE,
27 }
28 }
29}
30
31#[derive(Clone, Debug)]
32pub struct DexRequest {
33 client: Client,
34 endpoint: String,
35}
36
37#[derive(Debug)]
38pub enum DexError {
39 Serde(serde_json::Error),
40 Reqwest(reqwest::Error),
41 ServerResponse(String),
42 WebSocketError(String),
43 Other(String),
44 NoConnection,
45 UpcomingMaintenance,
46}
47
48impl From<ParseDecimalError> for DexError {
49 fn from(e: ParseDecimalError) -> Self {
50 DexError::Other(format!("{:?}", e))
51 }
52}
53
54impl Display for DexError {
55 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
56 match *self {
57 DexError::Serde(ref e) => write!(f, "Serde JSON error: {}", e),
58 DexError::Reqwest(ref e) => write!(f, "Reqwest error: {}", e),
59 DexError::ServerResponse(ref e) => write!(f, "Server response error: {}", e),
60 DexError::Other(ref e) => write!(f, "Other error: {}", e),
61 DexError::NoConnection => write!(f, "No running WebSocketConnection"),
62 DexError::WebSocketError(ref e) => write!(f, "WebSocket error: {}", e),
63 DexError::UpcomingMaintenance => write!(f, "Network upgrade scheduled in < 2h"),
64 }
65 }
66}
67
68impl StdError for DexError {
69 fn source(&self) -> Option<&(dyn StdError + 'static)> {
70 match *self {
71 DexError::Serde(ref e) => Some(e),
72 DexError::Reqwest(ref e) => Some(e),
73 DexError::ServerResponse(_) => None,
74 DexError::Other(_) => None,
75 DexError::NoConnection => None,
76 DexError::WebSocketError(_) => None,
77 DexError::UpcomingMaintenance => None,
78 }
79 }
80}
81
82impl From<reqwest::Error> for DexError {
83 fn from(error: reqwest::Error) -> Self {
84 DexError::Reqwest(error)
85 }
86}
87
88impl DexRequest {
89 pub async fn new(endpoint: String) -> Result<Self, DexError> {
90 let client = Client::builder().cookie_store(true).build()?;
91
92 Ok(DexRequest { client, endpoint })
93 }
94
95 pub async fn handle_request<T: serde::de::DeserializeOwned, U: Serialize + ?Sized>(
96 &self,
97 method: HttpMethod,
98 request_url: String,
99 headers: &HashMap<String, String>,
100 json_payload: String,
101 ) -> Result<T, DexError> {
102 let url = format!("{}{}", self.endpoint, request_url);
103
104 let mut header_map = HeaderMap::new();
105 header_map.insert(
106 reqwest::header::CONTENT_TYPE,
107 HeaderValue::from_static("application/json"),
108 );
109
110 for (key, value) in headers.iter() {
111 let key = reqwest::header::HeaderName::from_bytes(key.as_bytes())
112 .expect("Failed to create HeaderName");
113 let value = HeaderValue::from_str(value).expect("Failed to create HeaderValue");
114 header_map.insert(key, value);
115 }
116
117 let client = self.client.clone();
118 let request_builder = client
119 .request(Method::from(method), &url)
120 .headers(header_map);
121
122 log::trace!("payload = {}", json_payload);
123
124 let request_builder = if !json_payload.is_empty() {
125 request_builder.body(json_payload.clone())
126 } else {
127 request_builder
128 };
129
130 let response = request_builder.send().await.map_err(DexError::from)?;
131 let status = response.status();
132
133 if !status.is_success() {
134 let error_message =
135 format!("Server returned error: {}. requested url: {}", status, url);
136 log::error!("{}", &error_message);
137 }
138
139 let response_headers = response.headers().clone();
140 log::trace!("Response header: {:?}", response_headers);
141
142 let response_body = response.text().await.map_err(DexError::from)?;
143 log::trace!("Response body: {}", response_body);
144
145 serde_json::from_str(&response_body).map_err(|e| {
146 log::error!(
147 "Failed to deserialize response: {}, payload = {}",
148 e,
149 json_payload
150 );
151 DexError::Serde(e)
152 })
153 }
154}