binance_core/client/
synchronous.rs1use binance_common::error::BinanceError;
2use binance_common::url::UrlEncoded;
3use reqwest::{
4 Method, StatusCode,
5 blocking::{RequestBuilder, Response},
6};
7use serde::de::DeserializeOwned;
8
9use crate::signer::signature::Signature;
10
11pub struct Client<'a, S>
12where
13 S: Signature<'a>,
14{
15 host: &'a str,
16 signature: S,
17 inner_client: reqwest::blocking::Client,
18}
19
20impl<'a, S> Client<'a, S>
21where
22 S: Signature<'a>,
23{
24 pub fn new(host: &'a impl AsRef<str>, signature: S) -> Client<'a, S> {
25 Client {
26 host: host.as_ref(),
27 signature,
28 inner_client: reqwest::blocking::Client::new(),
29 }
30 }
31
32 pub fn get<T>(
33 &self,
34 path: impl AsRef<str>,
35 params: impl UrlEncoded,
36 ) -> std::result::Result<T, BinanceError>
37 where
38 T: DeserializeOwned,
39 {
40 let endpoint = format!("{}{}{}", self.host, path.as_ref(), params.to_url_encoded());
41
42 let response = self.inner_client.get(endpoint).send()?;
43
44 self.handle::<T>(response)
45 }
46
47 pub fn send<T>(
48 &self,
49 path: impl AsRef<str>,
50 params: impl UrlEncoded,
51 method: Method,
52 ) -> Result<T, BinanceError>
53 where
54 T: DeserializeOwned,
55 {
56 let request = self.signature.build_blocking_request(
57 &self.inner_client,
58 self.host,
59 path.as_ref(),
60 params.to_url_encoded().as_str(),
61 method,
62 )?;
63
64 let response = RequestBuilder::send(request)?;
65
66 self.handle(response)
67 }
68
69 pub fn handle<T: DeserializeOwned>(&self, response: Response) -> Result<T, BinanceError> {
70 let status = response.status();
71 let body = response.bytes()?;
72
73 match status {
74 StatusCode::BAD_REQUEST => {
75 let api_error: binance_common::error::ApiError =
76 serde_json::from_slice(&body).map_err(BinanceError::Deserialize)?;
77 Err(BinanceError::Api(api_error))
78 }
79
80 StatusCode::IM_A_TEAPOT => Err(BinanceError::IpBanned),
81
82 StatusCode::INTERNAL_SERVER_ERROR => Err(BinanceError::InternalServer),
83
84 StatusCode::OK => {
85 Ok(serde_json::from_slice::<T>(&body).map_err(BinanceError::Deserialize)?)
86 }
87
88 StatusCode::REQUEST_TIMEOUT => Err(BinanceError::RequestTimeout),
89 StatusCode::UNAUTHORIZED => {
90 let api_error: binance_common::error::ApiError =
91 serde_json::from_slice(&body).map_err(BinanceError::Deserialize)?;
92
93 Err(BinanceError::Api(api_error))
94 }
95 StatusCode::TOO_MANY_REQUESTS => Err(BinanceError::TooManyRequest),
96 status_code => Err(BinanceError::Unknown(format!(
97 "Response Status Code: {}",
98 status_code
99 ))),
100 }
101 }
102}