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