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