Skip to main content

binance_sdk/wallet/rest_api/apis/
others_api.rs

1/*
2 * Binance Wallet REST API
3 *
4 * OpenAPI Specification for the Binance Wallet REST API
5 *
6 * The version of the OpenAPI document: 1.0.0
7 *
8 *
9 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
10 * https://openapi-generator.tech
11 * Do not edit the class manually.
12 */
13
14#![allow(unused_imports)]
15use async_trait::async_trait;
16use derive_builder::Builder;
17use reqwest;
18use rust_decimal::prelude::*;
19use serde::{Deserialize, Serialize};
20use serde_json::{Value, json};
21use std::collections::BTreeMap;
22
23use crate::common::{
24    config::ConfigurationRestApi,
25    models::{ParamBuildError, RestApiResponse},
26    utils::send_request,
27};
28use crate::wallet::rest_api::models;
29
30const HAS_TIME_UNIT: bool = false;
31
32#[async_trait]
33pub trait OthersApi: Send + Sync {
34    async fn get_symbols_delist_schedule_for_spot(
35        &self,
36        params: GetSymbolsDelistScheduleForSpotParams,
37    ) -> anyhow::Result<RestApiResponse<Vec<models::GetSymbolsDelistScheduleForSpotResponseInner>>>;
38    async fn system_status(&self) -> anyhow::Result<RestApiResponse<models::SystemStatusResponse>>;
39}
40
41#[derive(Debug, Clone)]
42pub struct OthersApiClient {
43    configuration: ConfigurationRestApi,
44}
45
46impl OthersApiClient {
47    pub fn new(configuration: ConfigurationRestApi) -> Self {
48        Self { configuration }
49    }
50}
51
52/// Request parameters for the [`get_symbols_delist_schedule_for_spot`] operation.
53///
54/// This struct holds all of the inputs you can pass when calling
55/// [`get_symbols_delist_schedule_for_spot`](#method.get_symbols_delist_schedule_for_spot).
56#[derive(Clone, Debug, Builder, Default)]
57#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
58pub struct GetSymbolsDelistScheduleForSpotParams {
59    ///
60    /// The `recv_window` parameter.
61    ///
62    /// This field is **optional.
63    #[builder(setter(into), default)]
64    pub recv_window: Option<i64>,
65}
66
67impl GetSymbolsDelistScheduleForSpotParams {
68    /// Create a builder for [`get_symbols_delist_schedule_for_spot`].
69    ///
70    #[must_use]
71    pub fn builder() -> GetSymbolsDelistScheduleForSpotParamsBuilder {
72        GetSymbolsDelistScheduleForSpotParamsBuilder::default()
73    }
74}
75
76#[async_trait]
77impl OthersApi for OthersApiClient {
78    async fn get_symbols_delist_schedule_for_spot(
79        &self,
80        params: GetSymbolsDelistScheduleForSpotParams,
81    ) -> anyhow::Result<RestApiResponse<Vec<models::GetSymbolsDelistScheduleForSpotResponseInner>>>
82    {
83        let GetSymbolsDelistScheduleForSpotParams { recv_window } = params;
84
85        let mut query_params = BTreeMap::new();
86        let body_params = BTreeMap::new();
87
88        if let Some(rw) = recv_window {
89            query_params.insert("recvWindow".to_string(), json!(rw));
90        }
91
92        send_request::<Vec<models::GetSymbolsDelistScheduleForSpotResponseInner>>(
93            &self.configuration,
94            "/sapi/v1/spot/delist-schedule",
95            reqwest::Method::GET,
96            query_params,
97            body_params,
98            if HAS_TIME_UNIT {
99                self.configuration.time_unit
100            } else {
101                None
102            },
103            false,
104        )
105        .await
106    }
107
108    async fn system_status(&self) -> anyhow::Result<RestApiResponse<models::SystemStatusResponse>> {
109        let query_params = BTreeMap::new();
110        let body_params = BTreeMap::new();
111
112        send_request::<models::SystemStatusResponse>(
113            &self.configuration,
114            "/sapi/v1/system/status",
115            reqwest::Method::GET,
116            query_params,
117            body_params,
118            if HAS_TIME_UNIT {
119                self.configuration.time_unit
120            } else {
121                None
122            },
123            false,
124        )
125        .await
126    }
127}
128
129#[cfg(all(test, feature = "wallet"))]
130mod tests {
131    use super::*;
132    use crate::TOKIO_SHARED_RT;
133    use crate::{errors::ConnectorError, models::DataFuture, models::RestApiRateLimit};
134    use async_trait::async_trait;
135    use std::collections::HashMap;
136
137    struct DummyRestApiResponse<T> {
138        inner: Box<dyn FnOnce() -> DataFuture<Result<T, ConnectorError>> + Send + Sync>,
139        status: u16,
140        headers: HashMap<String, String>,
141        rate_limits: Option<Vec<RestApiRateLimit>>,
142    }
143
144    impl<T> From<DummyRestApiResponse<T>> for RestApiResponse<T> {
145        fn from(dummy: DummyRestApiResponse<T>) -> Self {
146            Self {
147                data_fn: dummy.inner,
148                status: dummy.status,
149                headers: dummy.headers,
150                rate_limits: dummy.rate_limits,
151            }
152        }
153    }
154
155    struct MockOthersApiClient {
156        force_error: bool,
157    }
158
159    #[async_trait]
160    impl OthersApi for MockOthersApiClient {
161        async fn get_symbols_delist_schedule_for_spot(
162            &self,
163            _params: GetSymbolsDelistScheduleForSpotParams,
164        ) -> anyhow::Result<
165            RestApiResponse<Vec<models::GetSymbolsDelistScheduleForSpotResponseInner>>,
166        > {
167            if self.force_error {
168                return Err(ConnectorError::ConnectorClientError {
169                    msg: "ResponseError".to_string(),
170                    code: None,
171                }
172                .into());
173            }
174
175            let resp_json: Value = serde_json::from_str(r#"[{"delistTime":1686161202000,"symbols":["ADAUSDT","BNBUSDT"]},{"delistTime":1686222232000,"symbols":["ETHUSDT"]}]"#).unwrap();
176            let dummy_response: Vec<models::GetSymbolsDelistScheduleForSpotResponseInner> =
177                serde_json::from_value(resp_json.clone()).expect(
178                    "should parse into Vec<models::GetSymbolsDelistScheduleForSpotResponseInner>",
179                );
180
181            let dummy = DummyRestApiResponse {
182                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
183                status: 200,
184                headers: HashMap::new(),
185                rate_limits: None,
186            };
187
188            Ok(dummy.into())
189        }
190
191        async fn system_status(
192            &self,
193        ) -> anyhow::Result<RestApiResponse<models::SystemStatusResponse>> {
194            if self.force_error {
195                return Err(ConnectorError::ConnectorClientError {
196                    msg: "ResponseError".to_string(),
197                    code: None,
198                }
199                .into());
200            }
201
202            let resp_json: Value = serde_json::from_str(r#"{"status":0,"msg":"normal"}"#).unwrap();
203            let dummy_response: models::SystemStatusResponse =
204                serde_json::from_value(resp_json.clone())
205                    .expect("should parse into models::SystemStatusResponse");
206
207            let dummy = DummyRestApiResponse {
208                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
209                status: 200,
210                headers: HashMap::new(),
211                rate_limits: None,
212            };
213
214            Ok(dummy.into())
215        }
216    }
217
218    #[test]
219    fn get_symbols_delist_schedule_for_spot_required_params_success() {
220        TOKIO_SHARED_RT.block_on(async {
221            let client = MockOthersApiClient { force_error: false };
222
223            let params = GetSymbolsDelistScheduleForSpotParams::builder().build().unwrap();
224
225            let resp_json: Value = serde_json::from_str(r#"[{"delistTime":1686161202000,"symbols":["ADAUSDT","BNBUSDT"]},{"delistTime":1686222232000,"symbols":["ETHUSDT"]}]"#).unwrap();
226            let expected_response : Vec<models::GetSymbolsDelistScheduleForSpotResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetSymbolsDelistScheduleForSpotResponseInner>");
227
228            let resp = client.get_symbols_delist_schedule_for_spot(params).await.expect("Expected a response");
229            let data_future = resp.data();
230            let actual_response = data_future.await.unwrap();
231            assert_eq!(actual_response, expected_response);
232        });
233    }
234
235    #[test]
236    fn get_symbols_delist_schedule_for_spot_optional_params_success() {
237        TOKIO_SHARED_RT.block_on(async {
238            let client = MockOthersApiClient { force_error: false };
239
240            let params = GetSymbolsDelistScheduleForSpotParams::builder().recv_window(5000).build().unwrap();
241
242            let resp_json: Value = serde_json::from_str(r#"[{"delistTime":1686161202000,"symbols":["ADAUSDT","BNBUSDT"]},{"delistTime":1686222232000,"symbols":["ETHUSDT"]}]"#).unwrap();
243            let expected_response : Vec<models::GetSymbolsDelistScheduleForSpotResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetSymbolsDelistScheduleForSpotResponseInner>");
244
245            let resp = client.get_symbols_delist_schedule_for_spot(params).await.expect("Expected a response");
246            let data_future = resp.data();
247            let actual_response = data_future.await.unwrap();
248            assert_eq!(actual_response, expected_response);
249        });
250    }
251
252    #[test]
253    fn get_symbols_delist_schedule_for_spot_response_error() {
254        TOKIO_SHARED_RT.block_on(async {
255            let client = MockOthersApiClient { force_error: true };
256
257            let params = GetSymbolsDelistScheduleForSpotParams::builder()
258                .build()
259                .unwrap();
260
261            match client.get_symbols_delist_schedule_for_spot(params).await {
262                Ok(_) => panic!("Expected an error"),
263                Err(err) => {
264                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
265                }
266            }
267        });
268    }
269
270    #[test]
271    fn system_status_required_params_success() {
272        TOKIO_SHARED_RT.block_on(async {
273            let client = MockOthersApiClient { force_error: false };
274
275            let resp_json: Value = serde_json::from_str(r#"{"status":0,"msg":"normal"}"#).unwrap();
276            let expected_response: models::SystemStatusResponse =
277                serde_json::from_value(resp_json.clone())
278                    .expect("should parse into models::SystemStatusResponse");
279
280            let resp = client.system_status().await.expect("Expected a response");
281            let data_future = resp.data();
282            let actual_response = data_future.await.unwrap();
283            assert_eq!(actual_response, expected_response);
284        });
285    }
286
287    #[test]
288    fn system_status_optional_params_success() {
289        TOKIO_SHARED_RT.block_on(async {
290            let client = MockOthersApiClient { force_error: false };
291
292            let resp_json: Value = serde_json::from_str(r#"{"status":0,"msg":"normal"}"#).unwrap();
293            let expected_response: models::SystemStatusResponse =
294                serde_json::from_value(resp_json.clone())
295                    .expect("should parse into models::SystemStatusResponse");
296
297            let resp = client.system_status().await.expect("Expected a response");
298            let data_future = resp.data();
299            let actual_response = data_future.await.unwrap();
300            assert_eq!(actual_response, expected_response);
301        });
302    }
303
304    #[test]
305    fn system_status_response_error() {
306        TOKIO_SHARED_RT.block_on(async {
307            let client = MockOthersApiClient { force_error: true };
308
309            match client.system_status().await {
310                Ok(_) => panic!("Expected an error"),
311                Err(err) => {
312                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
313                }
314            }
315        });
316    }
317}