Skip to main content

binance_sdk/spot/rest_api/apis/
account_api.rs

1/*
2 * Binance Spot REST API
3 *
4 * OpenAPI Specifications for the Binance Spot REST API
5 *
6 * API documents:
7 * - [Github rest-api documentation file](https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md)
8 * - [General API information for rest-api on website](https://developers.binance.com/docs/binance-spot-api-docs/rest-api/general-api-information)
9 *
10 *
11 * The version of the OpenAPI document: 1.0.0
12 *
13 *
14 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
15 * https://openapi-generator.tech
16 * Do not edit the class manually.
17 */
18
19#![allow(unused_imports)]
20use async_trait::async_trait;
21use derive_builder::Builder;
22use reqwest;
23use rust_decimal::prelude::*;
24use serde::{Deserialize, Serialize};
25use serde_json::{Value, json};
26use std::collections::BTreeMap;
27
28use crate::common::{
29    config::ConfigurationRestApi,
30    models::{ParamBuildError, RestApiResponse},
31    utils::send_request,
32};
33use crate::spot::rest_api::models;
34
35const HAS_TIME_UNIT: bool = true;
36
37#[async_trait]
38pub trait AccountApi: Send + Sync {
39    async fn account_commission(
40        &self,
41        params: AccountCommissionParams,
42    ) -> anyhow::Result<RestApiResponse<models::AccountCommissionResponse>>;
43    async fn all_order_list(
44        &self,
45        params: AllOrderListParams,
46    ) -> anyhow::Result<RestApiResponse<Vec<models::AllOrderListResponseInner>>>;
47    async fn all_orders(
48        &self,
49        params: AllOrdersParams,
50    ) -> anyhow::Result<RestApiResponse<Vec<models::AllOrdersResponseInner>>>;
51    async fn get_account(
52        &self,
53        params: GetAccountParams,
54    ) -> anyhow::Result<RestApiResponse<models::GetAccountResponse>>;
55    async fn get_open_orders(
56        &self,
57        params: GetOpenOrdersParams,
58    ) -> anyhow::Result<RestApiResponse<Vec<models::AllOrdersResponseInner>>>;
59    async fn get_order(
60        &self,
61        params: GetOrderParams,
62    ) -> anyhow::Result<RestApiResponse<models::GetOrderResponse>>;
63    async fn get_order_list(
64        &self,
65        params: GetOrderListParams,
66    ) -> anyhow::Result<RestApiResponse<models::GetOrderListResponse>>;
67    async fn my_allocations(
68        &self,
69        params: MyAllocationsParams,
70    ) -> anyhow::Result<RestApiResponse<Vec<models::MyAllocationsResponseInner>>>;
71    async fn my_filters(
72        &self,
73        params: MyFiltersParams,
74    ) -> anyhow::Result<RestApiResponse<models::MyFiltersResponse>>;
75    async fn my_prevented_matches(
76        &self,
77        params: MyPreventedMatchesParams,
78    ) -> anyhow::Result<RestApiResponse<Vec<models::MyPreventedMatchesResponseInner>>>;
79    async fn my_trades(
80        &self,
81        params: MyTradesParams,
82    ) -> anyhow::Result<RestApiResponse<Vec<models::MyTradesResponseInner>>>;
83    async fn open_order_list(
84        &self,
85        params: OpenOrderListParams,
86    ) -> anyhow::Result<RestApiResponse<Vec<models::OpenOrderListResponseInner>>>;
87    async fn order_amendments(
88        &self,
89        params: OrderAmendmentsParams,
90    ) -> anyhow::Result<RestApiResponse<Vec<models::OrderAmendmentsResponseInner>>>;
91    async fn rate_limit_order(
92        &self,
93        params: RateLimitOrderParams,
94    ) -> anyhow::Result<RestApiResponse<Vec<models::RateLimitOrderResponseInner>>>;
95}
96
97#[derive(Debug, Clone)]
98pub struct AccountApiClient {
99    configuration: ConfigurationRestApi,
100}
101
102impl AccountApiClient {
103    pub fn new(configuration: ConfigurationRestApi) -> Self {
104        Self { configuration }
105    }
106}
107
108/// Request parameters for the [`account_commission`] operation.
109///
110/// This struct holds all of the inputs you can pass when calling
111/// [`account_commission`](#method.account_commission).
112#[derive(Clone, Debug, Builder)]
113#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
114pub struct AccountCommissionParams {
115    ///
116    /// The `symbol` parameter.
117    ///
118    /// This field is **required.
119    #[builder(setter(into))]
120    pub symbol: String,
121}
122
123impl AccountCommissionParams {
124    /// Create a builder for [`account_commission`].
125    ///
126    /// Required parameters:
127    ///
128    /// * `symbol` — String
129    ///
130    #[must_use]
131    pub fn builder(symbol: String) -> AccountCommissionParamsBuilder {
132        AccountCommissionParamsBuilder::default().symbol(symbol)
133    }
134}
135/// Request parameters for the [`all_order_list`] operation.
136///
137/// This struct holds all of the inputs you can pass when calling
138/// [`all_order_list`](#method.all_order_list).
139#[derive(Clone, Debug, Builder, Default)]
140#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
141pub struct AllOrderListParams {
142    /// ID to get aggregate trades from INCLUSIVE.
143    ///
144    /// This field is **optional.
145    #[builder(setter(into), default)]
146    pub from_id: Option<i64>,
147    /// Timestamp in ms to get aggregate trades from INCLUSIVE.
148    ///
149    /// This field is **optional.
150    #[builder(setter(into), default)]
151    pub start_time: Option<i64>,
152    /// Timestamp in ms to get aggregate trades until INCLUSIVE.
153    ///
154    /// This field is **optional.
155    #[builder(setter(into), default)]
156    pub end_time: Option<i64>,
157    /// Default: 500; Maximum: 1000.
158    ///
159    /// This field is **optional.
160    #[builder(setter(into), default)]
161    pub limit: Option<i32>,
162    /// The value cannot be greater than `60000`. <br> Supports up to three decimal places of precision (e.g., 6000.346) so that microseconds may be specified.
163    ///
164    /// This field is **optional.
165    #[builder(setter(into), default)]
166    pub recv_window: Option<rust_decimal::Decimal>,
167}
168
169impl AllOrderListParams {
170    /// Create a builder for [`all_order_list`].
171    ///
172    #[must_use]
173    pub fn builder() -> AllOrderListParamsBuilder {
174        AllOrderListParamsBuilder::default()
175    }
176}
177/// Request parameters for the [`all_orders`] operation.
178///
179/// This struct holds all of the inputs you can pass when calling
180/// [`all_orders`](#method.all_orders).
181#[derive(Clone, Debug, Builder)]
182#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
183pub struct AllOrdersParams {
184    ///
185    /// The `symbol` parameter.
186    ///
187    /// This field is **required.
188    #[builder(setter(into))]
189    pub symbol: String,
190    ///
191    /// The `order_id` parameter.
192    ///
193    /// This field is **optional.
194    #[builder(setter(into), default)]
195    pub order_id: Option<i64>,
196    /// Timestamp in ms to get aggregate trades from INCLUSIVE.
197    ///
198    /// This field is **optional.
199    #[builder(setter(into), default)]
200    pub start_time: Option<i64>,
201    /// Timestamp in ms to get aggregate trades until INCLUSIVE.
202    ///
203    /// This field is **optional.
204    #[builder(setter(into), default)]
205    pub end_time: Option<i64>,
206    /// Default: 500; Maximum: 1000.
207    ///
208    /// This field is **optional.
209    #[builder(setter(into), default)]
210    pub limit: Option<i32>,
211    /// The value cannot be greater than `60000`. <br> Supports up to three decimal places of precision (e.g., 6000.346) so that microseconds may be specified.
212    ///
213    /// This field is **optional.
214    #[builder(setter(into), default)]
215    pub recv_window: Option<rust_decimal::Decimal>,
216}
217
218impl AllOrdersParams {
219    /// Create a builder for [`all_orders`].
220    ///
221    /// Required parameters:
222    ///
223    /// * `symbol` — String
224    ///
225    #[must_use]
226    pub fn builder(symbol: String) -> AllOrdersParamsBuilder {
227        AllOrdersParamsBuilder::default().symbol(symbol)
228    }
229}
230/// Request parameters for the [`get_account`] operation.
231///
232/// This struct holds all of the inputs you can pass when calling
233/// [`get_account`](#method.get_account).
234#[derive(Clone, Debug, Builder, Default)]
235#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
236pub struct GetAccountParams {
237    /// When set to `true`, emits only the non-zero balances of an account. <br>Default value: `false`
238    ///
239    /// This field is **optional.
240    #[builder(setter(into), default)]
241    pub omit_zero_balances: Option<bool>,
242    /// The value cannot be greater than `60000`. <br> Supports up to three decimal places of precision (e.g., 6000.346) so that microseconds may be specified.
243    ///
244    /// This field is **optional.
245    #[builder(setter(into), default)]
246    pub recv_window: Option<rust_decimal::Decimal>,
247}
248
249impl GetAccountParams {
250    /// Create a builder for [`get_account`].
251    ///
252    #[must_use]
253    pub fn builder() -> GetAccountParamsBuilder {
254        GetAccountParamsBuilder::default()
255    }
256}
257/// Request parameters for the [`get_open_orders`] operation.
258///
259/// This struct holds all of the inputs you can pass when calling
260/// [`get_open_orders`](#method.get_open_orders).
261#[derive(Clone, Debug, Builder, Default)]
262#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
263pub struct GetOpenOrdersParams {
264    /// Symbol to query
265    ///
266    /// This field is **optional.
267    #[builder(setter(into), default)]
268    pub symbol: Option<String>,
269    /// The value cannot be greater than `60000`. <br> Supports up to three decimal places of precision (e.g., 6000.346) so that microseconds may be specified.
270    ///
271    /// This field is **optional.
272    #[builder(setter(into), default)]
273    pub recv_window: Option<rust_decimal::Decimal>,
274}
275
276impl GetOpenOrdersParams {
277    /// Create a builder for [`get_open_orders`].
278    ///
279    #[must_use]
280    pub fn builder() -> GetOpenOrdersParamsBuilder {
281        GetOpenOrdersParamsBuilder::default()
282    }
283}
284/// Request parameters for the [`get_order`] operation.
285///
286/// This struct holds all of the inputs you can pass when calling
287/// [`get_order`](#method.get_order).
288#[derive(Clone, Debug, Builder)]
289#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
290pub struct GetOrderParams {
291    ///
292    /// The `symbol` parameter.
293    ///
294    /// This field is **required.
295    #[builder(setter(into))]
296    pub symbol: String,
297    ///
298    /// The `order_id` parameter.
299    ///
300    /// This field is **optional.
301    #[builder(setter(into), default)]
302    pub order_id: Option<i64>,
303    ///
304    /// The `orig_client_order_id` parameter.
305    ///
306    /// This field is **optional.
307    #[builder(setter(into), default)]
308    pub orig_client_order_id: Option<String>,
309    /// The value cannot be greater than `60000`. <br> Supports up to three decimal places of precision (e.g., 6000.346) so that microseconds may be specified.
310    ///
311    /// This field is **optional.
312    #[builder(setter(into), default)]
313    pub recv_window: Option<rust_decimal::Decimal>,
314}
315
316impl GetOrderParams {
317    /// Create a builder for [`get_order`].
318    ///
319    /// Required parameters:
320    ///
321    /// * `symbol` — String
322    ///
323    #[must_use]
324    pub fn builder(symbol: String) -> GetOrderParamsBuilder {
325        GetOrderParamsBuilder::default().symbol(symbol)
326    }
327}
328/// Request parameters for the [`get_order_list`] operation.
329///
330/// This struct holds all of the inputs you can pass when calling
331/// [`get_order_list`](#method.get_order_list).
332#[derive(Clone, Debug, Builder, Default)]
333#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
334pub struct GetOrderListParams {
335    /// Either `orderListId` or `listClientOrderId` must be provided
336    ///
337    /// This field is **optional.
338    #[builder(setter(into), default)]
339    pub order_list_id: Option<i64>,
340    ///
341    /// The `orig_client_order_id` parameter.
342    ///
343    /// This field is **optional.
344    #[builder(setter(into), default)]
345    pub orig_client_order_id: Option<String>,
346    /// The value cannot be greater than `60000`. <br> Supports up to three decimal places of precision (e.g., 6000.346) so that microseconds may be specified.
347    ///
348    /// This field is **optional.
349    #[builder(setter(into), default)]
350    pub recv_window: Option<rust_decimal::Decimal>,
351}
352
353impl GetOrderListParams {
354    /// Create a builder for [`get_order_list`].
355    ///
356    #[must_use]
357    pub fn builder() -> GetOrderListParamsBuilder {
358        GetOrderListParamsBuilder::default()
359    }
360}
361/// Request parameters for the [`my_allocations`] operation.
362///
363/// This struct holds all of the inputs you can pass when calling
364/// [`my_allocations`](#method.my_allocations).
365#[derive(Clone, Debug, Builder)]
366#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
367pub struct MyAllocationsParams {
368    ///
369    /// The `symbol` parameter.
370    ///
371    /// This field is **required.
372    #[builder(setter(into))]
373    pub symbol: String,
374    /// Timestamp in ms to get aggregate trades from INCLUSIVE.
375    ///
376    /// This field is **optional.
377    #[builder(setter(into), default)]
378    pub start_time: Option<i64>,
379    /// Timestamp in ms to get aggregate trades until INCLUSIVE.
380    ///
381    /// This field is **optional.
382    #[builder(setter(into), default)]
383    pub end_time: Option<i64>,
384    ///
385    /// The `from_allocation_id` parameter.
386    ///
387    /// This field is **optional.
388    #[builder(setter(into), default)]
389    pub from_allocation_id: Option<i32>,
390    /// Default: 500; Maximum: 1000.
391    ///
392    /// This field is **optional.
393    #[builder(setter(into), default)]
394    pub limit: Option<i32>,
395    ///
396    /// The `order_id` parameter.
397    ///
398    /// This field is **optional.
399    #[builder(setter(into), default)]
400    pub order_id: Option<i64>,
401    /// The value cannot be greater than `60000`. <br> Supports up to three decimal places of precision (e.g., 6000.346) so that microseconds may be specified.
402    ///
403    /// This field is **optional.
404    #[builder(setter(into), default)]
405    pub recv_window: Option<rust_decimal::Decimal>,
406}
407
408impl MyAllocationsParams {
409    /// Create a builder for [`my_allocations`].
410    ///
411    /// Required parameters:
412    ///
413    /// * `symbol` — String
414    ///
415    #[must_use]
416    pub fn builder(symbol: String) -> MyAllocationsParamsBuilder {
417        MyAllocationsParamsBuilder::default().symbol(symbol)
418    }
419}
420/// Request parameters for the [`my_filters`] operation.
421///
422/// This struct holds all of the inputs you can pass when calling
423/// [`my_filters`](#method.my_filters).
424#[derive(Clone, Debug, Builder)]
425#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
426pub struct MyFiltersParams {
427    ///
428    /// The `symbol` parameter.
429    ///
430    /// This field is **required.
431    #[builder(setter(into))]
432    pub symbol: String,
433    /// The value cannot be greater than `60000`. <br> Supports up to three decimal places of precision (e.g., 6000.346) so that microseconds may be specified.
434    ///
435    /// This field is **optional.
436    #[builder(setter(into), default)]
437    pub recv_window: Option<rust_decimal::Decimal>,
438}
439
440impl MyFiltersParams {
441    /// Create a builder for [`my_filters`].
442    ///
443    /// Required parameters:
444    ///
445    /// * `symbol` — String
446    ///
447    #[must_use]
448    pub fn builder(symbol: String) -> MyFiltersParamsBuilder {
449        MyFiltersParamsBuilder::default().symbol(symbol)
450    }
451}
452/// Request parameters for the [`my_prevented_matches`] operation.
453///
454/// This struct holds all of the inputs you can pass when calling
455/// [`my_prevented_matches`](#method.my_prevented_matches).
456#[derive(Clone, Debug, Builder)]
457#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
458pub struct MyPreventedMatchesParams {
459    ///
460    /// The `symbol` parameter.
461    ///
462    /// This field is **required.
463    #[builder(setter(into))]
464    pub symbol: String,
465    ///
466    /// The `prevented_match_id` parameter.
467    ///
468    /// This field is **optional.
469    #[builder(setter(into), default)]
470    pub prevented_match_id: Option<i64>,
471    ///
472    /// The `order_id` parameter.
473    ///
474    /// This field is **optional.
475    #[builder(setter(into), default)]
476    pub order_id: Option<i64>,
477    ///
478    /// The `from_prevented_match_id` parameter.
479    ///
480    /// This field is **optional.
481    #[builder(setter(into), default)]
482    pub from_prevented_match_id: Option<i64>,
483    /// Default: 500; Maximum: 1000.
484    ///
485    /// This field is **optional.
486    #[builder(setter(into), default)]
487    pub limit: Option<i32>,
488    /// The value cannot be greater than `60000`. <br> Supports up to three decimal places of precision (e.g., 6000.346) so that microseconds may be specified.
489    ///
490    /// This field is **optional.
491    #[builder(setter(into), default)]
492    pub recv_window: Option<rust_decimal::Decimal>,
493}
494
495impl MyPreventedMatchesParams {
496    /// Create a builder for [`my_prevented_matches`].
497    ///
498    /// Required parameters:
499    ///
500    /// * `symbol` — String
501    ///
502    #[must_use]
503    pub fn builder(symbol: String) -> MyPreventedMatchesParamsBuilder {
504        MyPreventedMatchesParamsBuilder::default().symbol(symbol)
505    }
506}
507/// Request parameters for the [`my_trades`] operation.
508///
509/// This struct holds all of the inputs you can pass when calling
510/// [`my_trades`](#method.my_trades).
511#[derive(Clone, Debug, Builder)]
512#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
513pub struct MyTradesParams {
514    ///
515    /// The `symbol` parameter.
516    ///
517    /// This field is **required.
518    #[builder(setter(into))]
519    pub symbol: String,
520    ///
521    /// The `order_id` parameter.
522    ///
523    /// This field is **optional.
524    #[builder(setter(into), default)]
525    pub order_id: Option<i64>,
526    /// Timestamp in ms to get aggregate trades from INCLUSIVE.
527    ///
528    /// This field is **optional.
529    #[builder(setter(into), default)]
530    pub start_time: Option<i64>,
531    /// Timestamp in ms to get aggregate trades until INCLUSIVE.
532    ///
533    /// This field is **optional.
534    #[builder(setter(into), default)]
535    pub end_time: Option<i64>,
536    /// ID to get aggregate trades from INCLUSIVE.
537    ///
538    /// This field is **optional.
539    #[builder(setter(into), default)]
540    pub from_id: Option<i64>,
541    /// Default: 500; Maximum: 1000.
542    ///
543    /// This field is **optional.
544    #[builder(setter(into), default)]
545    pub limit: Option<i32>,
546    /// The value cannot be greater than `60000`. <br> Supports up to three decimal places of precision (e.g., 6000.346) so that microseconds may be specified.
547    ///
548    /// This field is **optional.
549    #[builder(setter(into), default)]
550    pub recv_window: Option<rust_decimal::Decimal>,
551}
552
553impl MyTradesParams {
554    /// Create a builder for [`my_trades`].
555    ///
556    /// Required parameters:
557    ///
558    /// * `symbol` — String
559    ///
560    #[must_use]
561    pub fn builder(symbol: String) -> MyTradesParamsBuilder {
562        MyTradesParamsBuilder::default().symbol(symbol)
563    }
564}
565/// Request parameters for the [`open_order_list`] operation.
566///
567/// This struct holds all of the inputs you can pass when calling
568/// [`open_order_list`](#method.open_order_list).
569#[derive(Clone, Debug, Builder, Default)]
570#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
571pub struct OpenOrderListParams {
572    /// The value cannot be greater than `60000`. <br> Supports up to three decimal places of precision (e.g., 6000.346) so that microseconds may be specified.
573    ///
574    /// This field is **optional.
575    #[builder(setter(into), default)]
576    pub recv_window: Option<rust_decimal::Decimal>,
577}
578
579impl OpenOrderListParams {
580    /// Create a builder for [`open_order_list`].
581    ///
582    #[must_use]
583    pub fn builder() -> OpenOrderListParamsBuilder {
584        OpenOrderListParamsBuilder::default()
585    }
586}
587/// Request parameters for the [`order_amendments`] operation.
588///
589/// This struct holds all of the inputs you can pass when calling
590/// [`order_amendments`](#method.order_amendments).
591#[derive(Clone, Debug, Builder)]
592#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
593pub struct OrderAmendmentsParams {
594    ///
595    /// The `symbol` parameter.
596    ///
597    /// This field is **required.
598    #[builder(setter(into))]
599    pub symbol: String,
600    ///
601    /// The `order_id` parameter.
602    ///
603    /// This field is **required.
604    #[builder(setter(into))]
605    pub order_id: i64,
606    ///
607    /// The `from_execution_id` parameter.
608    ///
609    /// This field is **optional.
610    #[builder(setter(into), default)]
611    pub from_execution_id: Option<i64>,
612    /// Default: 500; Maximum: 1000
613    ///
614    /// This field is **optional.
615    #[builder(setter(into), default)]
616    pub limit: Option<i64>,
617    /// The value cannot be greater than `60000`. <br> Supports up to three decimal places of precision (e.g., 6000.346) so that microseconds may be specified.
618    ///
619    /// This field is **optional.
620    #[builder(setter(into), default)]
621    pub recv_window: Option<rust_decimal::Decimal>,
622}
623
624impl OrderAmendmentsParams {
625    /// Create a builder for [`order_amendments`].
626    ///
627    /// Required parameters:
628    ///
629    /// * `symbol` — String
630    /// * `order_id` — i64
631    ///
632    #[must_use]
633    pub fn builder(symbol: String, order_id: i64) -> OrderAmendmentsParamsBuilder {
634        OrderAmendmentsParamsBuilder::default()
635            .symbol(symbol)
636            .order_id(order_id)
637    }
638}
639/// Request parameters for the [`rate_limit_order`] operation.
640///
641/// This struct holds all of the inputs you can pass when calling
642/// [`rate_limit_order`](#method.rate_limit_order).
643#[derive(Clone, Debug, Builder, Default)]
644#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
645pub struct RateLimitOrderParams {
646    /// The value cannot be greater than `60000`. <br> Supports up to three decimal places of precision (e.g., 6000.346) so that microseconds may be specified.
647    ///
648    /// This field is **optional.
649    #[builder(setter(into), default)]
650    pub recv_window: Option<rust_decimal::Decimal>,
651}
652
653impl RateLimitOrderParams {
654    /// Create a builder for [`rate_limit_order`].
655    ///
656    #[must_use]
657    pub fn builder() -> RateLimitOrderParamsBuilder {
658        RateLimitOrderParamsBuilder::default()
659    }
660}
661
662#[async_trait]
663impl AccountApi for AccountApiClient {
664    async fn account_commission(
665        &self,
666        params: AccountCommissionParams,
667    ) -> anyhow::Result<RestApiResponse<models::AccountCommissionResponse>> {
668        let AccountCommissionParams { symbol } = params;
669
670        let mut query_params = BTreeMap::new();
671        let body_params = BTreeMap::new();
672
673        query_params.insert("symbol".to_string(), json!(symbol));
674
675        send_request::<models::AccountCommissionResponse>(
676            &self.configuration,
677            "/api/v3/account/commission",
678            reqwest::Method::GET,
679            query_params,
680            body_params,
681            if HAS_TIME_UNIT {
682                self.configuration.time_unit
683            } else {
684                None
685            },
686            true,
687        )
688        .await
689    }
690
691    async fn all_order_list(
692        &self,
693        params: AllOrderListParams,
694    ) -> anyhow::Result<RestApiResponse<Vec<models::AllOrderListResponseInner>>> {
695        let AllOrderListParams {
696            from_id,
697            start_time,
698            end_time,
699            limit,
700            recv_window,
701        } = params;
702
703        let mut query_params = BTreeMap::new();
704        let body_params = BTreeMap::new();
705
706        if let Some(rw) = from_id {
707            query_params.insert("fromId".to_string(), json!(rw));
708        }
709
710        if let Some(rw) = start_time {
711            query_params.insert("startTime".to_string(), json!(rw));
712        }
713
714        if let Some(rw) = end_time {
715            query_params.insert("endTime".to_string(), json!(rw));
716        }
717
718        if let Some(rw) = limit {
719            query_params.insert("limit".to_string(), json!(rw));
720        }
721
722        if let Some(rw) = recv_window {
723            query_params.insert("recvWindow".to_string(), json!(rw));
724        }
725
726        send_request::<Vec<models::AllOrderListResponseInner>>(
727            &self.configuration,
728            "/api/v3/allOrderList",
729            reqwest::Method::GET,
730            query_params,
731            body_params,
732            if HAS_TIME_UNIT {
733                self.configuration.time_unit
734            } else {
735                None
736            },
737            true,
738        )
739        .await
740    }
741
742    async fn all_orders(
743        &self,
744        params: AllOrdersParams,
745    ) -> anyhow::Result<RestApiResponse<Vec<models::AllOrdersResponseInner>>> {
746        let AllOrdersParams {
747            symbol,
748            order_id,
749            start_time,
750            end_time,
751            limit,
752            recv_window,
753        } = params;
754
755        let mut query_params = BTreeMap::new();
756        let body_params = BTreeMap::new();
757
758        query_params.insert("symbol".to_string(), json!(symbol));
759
760        if let Some(rw) = order_id {
761            query_params.insert("orderId".to_string(), json!(rw));
762        }
763
764        if let Some(rw) = start_time {
765            query_params.insert("startTime".to_string(), json!(rw));
766        }
767
768        if let Some(rw) = end_time {
769            query_params.insert("endTime".to_string(), json!(rw));
770        }
771
772        if let Some(rw) = limit {
773            query_params.insert("limit".to_string(), json!(rw));
774        }
775
776        if let Some(rw) = recv_window {
777            query_params.insert("recvWindow".to_string(), json!(rw));
778        }
779
780        send_request::<Vec<models::AllOrdersResponseInner>>(
781            &self.configuration,
782            "/api/v3/allOrders",
783            reqwest::Method::GET,
784            query_params,
785            body_params,
786            if HAS_TIME_UNIT {
787                self.configuration.time_unit
788            } else {
789                None
790            },
791            true,
792        )
793        .await
794    }
795
796    async fn get_account(
797        &self,
798        params: GetAccountParams,
799    ) -> anyhow::Result<RestApiResponse<models::GetAccountResponse>> {
800        let GetAccountParams {
801            omit_zero_balances,
802            recv_window,
803        } = params;
804
805        let mut query_params = BTreeMap::new();
806        let body_params = BTreeMap::new();
807
808        if let Some(rw) = omit_zero_balances {
809            query_params.insert("omitZeroBalances".to_string(), json!(rw));
810        }
811
812        if let Some(rw) = recv_window {
813            query_params.insert("recvWindow".to_string(), json!(rw));
814        }
815
816        send_request::<models::GetAccountResponse>(
817            &self.configuration,
818            "/api/v3/account",
819            reqwest::Method::GET,
820            query_params,
821            body_params,
822            if HAS_TIME_UNIT {
823                self.configuration.time_unit
824            } else {
825                None
826            },
827            true,
828        )
829        .await
830    }
831
832    async fn get_open_orders(
833        &self,
834        params: GetOpenOrdersParams,
835    ) -> anyhow::Result<RestApiResponse<Vec<models::AllOrdersResponseInner>>> {
836        let GetOpenOrdersParams {
837            symbol,
838            recv_window,
839        } = params;
840
841        let mut query_params = BTreeMap::new();
842        let body_params = BTreeMap::new();
843
844        if let Some(rw) = symbol {
845            query_params.insert("symbol".to_string(), json!(rw));
846        }
847
848        if let Some(rw) = recv_window {
849            query_params.insert("recvWindow".to_string(), json!(rw));
850        }
851
852        send_request::<Vec<models::AllOrdersResponseInner>>(
853            &self.configuration,
854            "/api/v3/openOrders",
855            reqwest::Method::GET,
856            query_params,
857            body_params,
858            if HAS_TIME_UNIT {
859                self.configuration.time_unit
860            } else {
861                None
862            },
863            true,
864        )
865        .await
866    }
867
868    async fn get_order(
869        &self,
870        params: GetOrderParams,
871    ) -> anyhow::Result<RestApiResponse<models::GetOrderResponse>> {
872        let GetOrderParams {
873            symbol,
874            order_id,
875            orig_client_order_id,
876            recv_window,
877        } = params;
878
879        let mut query_params = BTreeMap::new();
880        let body_params = BTreeMap::new();
881
882        query_params.insert("symbol".to_string(), json!(symbol));
883
884        if let Some(rw) = order_id {
885            query_params.insert("orderId".to_string(), json!(rw));
886        }
887
888        if let Some(rw) = orig_client_order_id {
889            query_params.insert("origClientOrderId".to_string(), json!(rw));
890        }
891
892        if let Some(rw) = recv_window {
893            query_params.insert("recvWindow".to_string(), json!(rw));
894        }
895
896        send_request::<models::GetOrderResponse>(
897            &self.configuration,
898            "/api/v3/order",
899            reqwest::Method::GET,
900            query_params,
901            body_params,
902            if HAS_TIME_UNIT {
903                self.configuration.time_unit
904            } else {
905                None
906            },
907            true,
908        )
909        .await
910    }
911
912    async fn get_order_list(
913        &self,
914        params: GetOrderListParams,
915    ) -> anyhow::Result<RestApiResponse<models::GetOrderListResponse>> {
916        let GetOrderListParams {
917            order_list_id,
918            orig_client_order_id,
919            recv_window,
920        } = params;
921
922        let mut query_params = BTreeMap::new();
923        let body_params = BTreeMap::new();
924
925        if let Some(rw) = order_list_id {
926            query_params.insert("orderListId".to_string(), json!(rw));
927        }
928
929        if let Some(rw) = orig_client_order_id {
930            query_params.insert("origClientOrderId".to_string(), json!(rw));
931        }
932
933        if let Some(rw) = recv_window {
934            query_params.insert("recvWindow".to_string(), json!(rw));
935        }
936
937        send_request::<models::GetOrderListResponse>(
938            &self.configuration,
939            "/api/v3/orderList",
940            reqwest::Method::GET,
941            query_params,
942            body_params,
943            if HAS_TIME_UNIT {
944                self.configuration.time_unit
945            } else {
946                None
947            },
948            true,
949        )
950        .await
951    }
952
953    async fn my_allocations(
954        &self,
955        params: MyAllocationsParams,
956    ) -> anyhow::Result<RestApiResponse<Vec<models::MyAllocationsResponseInner>>> {
957        let MyAllocationsParams {
958            symbol,
959            start_time,
960            end_time,
961            from_allocation_id,
962            limit,
963            order_id,
964            recv_window,
965        } = params;
966
967        let mut query_params = BTreeMap::new();
968        let body_params = BTreeMap::new();
969
970        query_params.insert("symbol".to_string(), json!(symbol));
971
972        if let Some(rw) = start_time {
973            query_params.insert("startTime".to_string(), json!(rw));
974        }
975
976        if let Some(rw) = end_time {
977            query_params.insert("endTime".to_string(), json!(rw));
978        }
979
980        if let Some(rw) = from_allocation_id {
981            query_params.insert("fromAllocationId".to_string(), json!(rw));
982        }
983
984        if let Some(rw) = limit {
985            query_params.insert("limit".to_string(), json!(rw));
986        }
987
988        if let Some(rw) = order_id {
989            query_params.insert("orderId".to_string(), json!(rw));
990        }
991
992        if let Some(rw) = recv_window {
993            query_params.insert("recvWindow".to_string(), json!(rw));
994        }
995
996        send_request::<Vec<models::MyAllocationsResponseInner>>(
997            &self.configuration,
998            "/api/v3/myAllocations",
999            reqwest::Method::GET,
1000            query_params,
1001            body_params,
1002            if HAS_TIME_UNIT {
1003                self.configuration.time_unit
1004            } else {
1005                None
1006            },
1007            true,
1008        )
1009        .await
1010    }
1011
1012    async fn my_filters(
1013        &self,
1014        params: MyFiltersParams,
1015    ) -> anyhow::Result<RestApiResponse<models::MyFiltersResponse>> {
1016        let MyFiltersParams {
1017            symbol,
1018            recv_window,
1019        } = params;
1020
1021        let mut query_params = BTreeMap::new();
1022        let body_params = BTreeMap::new();
1023
1024        query_params.insert("symbol".to_string(), json!(symbol));
1025
1026        if let Some(rw) = recv_window {
1027            query_params.insert("recvWindow".to_string(), json!(rw));
1028        }
1029
1030        send_request::<models::MyFiltersResponse>(
1031            &self.configuration,
1032            "/api/v3/myFilters",
1033            reqwest::Method::GET,
1034            query_params,
1035            body_params,
1036            if HAS_TIME_UNIT {
1037                self.configuration.time_unit
1038            } else {
1039                None
1040            },
1041            true,
1042        )
1043        .await
1044    }
1045
1046    async fn my_prevented_matches(
1047        &self,
1048        params: MyPreventedMatchesParams,
1049    ) -> anyhow::Result<RestApiResponse<Vec<models::MyPreventedMatchesResponseInner>>> {
1050        let MyPreventedMatchesParams {
1051            symbol,
1052            prevented_match_id,
1053            order_id,
1054            from_prevented_match_id,
1055            limit,
1056            recv_window,
1057        } = params;
1058
1059        let mut query_params = BTreeMap::new();
1060        let body_params = BTreeMap::new();
1061
1062        query_params.insert("symbol".to_string(), json!(symbol));
1063
1064        if let Some(rw) = prevented_match_id {
1065            query_params.insert("preventedMatchId".to_string(), json!(rw));
1066        }
1067
1068        if let Some(rw) = order_id {
1069            query_params.insert("orderId".to_string(), json!(rw));
1070        }
1071
1072        if let Some(rw) = from_prevented_match_id {
1073            query_params.insert("fromPreventedMatchId".to_string(), json!(rw));
1074        }
1075
1076        if let Some(rw) = limit {
1077            query_params.insert("limit".to_string(), json!(rw));
1078        }
1079
1080        if let Some(rw) = recv_window {
1081            query_params.insert("recvWindow".to_string(), json!(rw));
1082        }
1083
1084        send_request::<Vec<models::MyPreventedMatchesResponseInner>>(
1085            &self.configuration,
1086            "/api/v3/myPreventedMatches",
1087            reqwest::Method::GET,
1088            query_params,
1089            body_params,
1090            if HAS_TIME_UNIT {
1091                self.configuration.time_unit
1092            } else {
1093                None
1094            },
1095            true,
1096        )
1097        .await
1098    }
1099
1100    async fn my_trades(
1101        &self,
1102        params: MyTradesParams,
1103    ) -> anyhow::Result<RestApiResponse<Vec<models::MyTradesResponseInner>>> {
1104        let MyTradesParams {
1105            symbol,
1106            order_id,
1107            start_time,
1108            end_time,
1109            from_id,
1110            limit,
1111            recv_window,
1112        } = params;
1113
1114        let mut query_params = BTreeMap::new();
1115        let body_params = BTreeMap::new();
1116
1117        query_params.insert("symbol".to_string(), json!(symbol));
1118
1119        if let Some(rw) = order_id {
1120            query_params.insert("orderId".to_string(), json!(rw));
1121        }
1122
1123        if let Some(rw) = start_time {
1124            query_params.insert("startTime".to_string(), json!(rw));
1125        }
1126
1127        if let Some(rw) = end_time {
1128            query_params.insert("endTime".to_string(), json!(rw));
1129        }
1130
1131        if let Some(rw) = from_id {
1132            query_params.insert("fromId".to_string(), json!(rw));
1133        }
1134
1135        if let Some(rw) = limit {
1136            query_params.insert("limit".to_string(), json!(rw));
1137        }
1138
1139        if let Some(rw) = recv_window {
1140            query_params.insert("recvWindow".to_string(), json!(rw));
1141        }
1142
1143        send_request::<Vec<models::MyTradesResponseInner>>(
1144            &self.configuration,
1145            "/api/v3/myTrades",
1146            reqwest::Method::GET,
1147            query_params,
1148            body_params,
1149            if HAS_TIME_UNIT {
1150                self.configuration.time_unit
1151            } else {
1152                None
1153            },
1154            true,
1155        )
1156        .await
1157    }
1158
1159    async fn open_order_list(
1160        &self,
1161        params: OpenOrderListParams,
1162    ) -> anyhow::Result<RestApiResponse<Vec<models::OpenOrderListResponseInner>>> {
1163        let OpenOrderListParams { recv_window } = params;
1164
1165        let mut query_params = BTreeMap::new();
1166        let body_params = BTreeMap::new();
1167
1168        if let Some(rw) = recv_window {
1169            query_params.insert("recvWindow".to_string(), json!(rw));
1170        }
1171
1172        send_request::<Vec<models::OpenOrderListResponseInner>>(
1173            &self.configuration,
1174            "/api/v3/openOrderList",
1175            reqwest::Method::GET,
1176            query_params,
1177            body_params,
1178            if HAS_TIME_UNIT {
1179                self.configuration.time_unit
1180            } else {
1181                None
1182            },
1183            true,
1184        )
1185        .await
1186    }
1187
1188    async fn order_amendments(
1189        &self,
1190        params: OrderAmendmentsParams,
1191    ) -> anyhow::Result<RestApiResponse<Vec<models::OrderAmendmentsResponseInner>>> {
1192        let OrderAmendmentsParams {
1193            symbol,
1194            order_id,
1195            from_execution_id,
1196            limit,
1197            recv_window,
1198        } = params;
1199
1200        let mut query_params = BTreeMap::new();
1201        let body_params = BTreeMap::new();
1202
1203        query_params.insert("symbol".to_string(), json!(symbol));
1204
1205        query_params.insert("orderId".to_string(), json!(order_id));
1206
1207        if let Some(rw) = from_execution_id {
1208            query_params.insert("fromExecutionId".to_string(), json!(rw));
1209        }
1210
1211        if let Some(rw) = limit {
1212            query_params.insert("limit".to_string(), json!(rw));
1213        }
1214
1215        if let Some(rw) = recv_window {
1216            query_params.insert("recvWindow".to_string(), json!(rw));
1217        }
1218
1219        send_request::<Vec<models::OrderAmendmentsResponseInner>>(
1220            &self.configuration,
1221            "/api/v3/order/amendments",
1222            reqwest::Method::GET,
1223            query_params,
1224            body_params,
1225            if HAS_TIME_UNIT {
1226                self.configuration.time_unit
1227            } else {
1228                None
1229            },
1230            true,
1231        )
1232        .await
1233    }
1234
1235    async fn rate_limit_order(
1236        &self,
1237        params: RateLimitOrderParams,
1238    ) -> anyhow::Result<RestApiResponse<Vec<models::RateLimitOrderResponseInner>>> {
1239        let RateLimitOrderParams { recv_window } = params;
1240
1241        let mut query_params = BTreeMap::new();
1242        let body_params = BTreeMap::new();
1243
1244        if let Some(rw) = recv_window {
1245            query_params.insert("recvWindow".to_string(), json!(rw));
1246        }
1247
1248        send_request::<Vec<models::RateLimitOrderResponseInner>>(
1249            &self.configuration,
1250            "/api/v3/rateLimit/order",
1251            reqwest::Method::GET,
1252            query_params,
1253            body_params,
1254            if HAS_TIME_UNIT {
1255                self.configuration.time_unit
1256            } else {
1257                None
1258            },
1259            true,
1260        )
1261        .await
1262    }
1263}
1264
1265#[cfg(all(test, feature = "spot"))]
1266mod tests {
1267    use super::*;
1268    use crate::TOKIO_SHARED_RT;
1269    use crate::{errors::ConnectorError, models::DataFuture, models::RestApiRateLimit};
1270    use async_trait::async_trait;
1271    use std::collections::HashMap;
1272
1273    struct DummyRestApiResponse<T> {
1274        inner: Box<dyn FnOnce() -> DataFuture<Result<T, ConnectorError>> + Send + Sync>,
1275        status: u16,
1276        headers: HashMap<String, String>,
1277        rate_limits: Option<Vec<RestApiRateLimit>>,
1278    }
1279
1280    impl<T> From<DummyRestApiResponse<T>> for RestApiResponse<T> {
1281        fn from(dummy: DummyRestApiResponse<T>) -> Self {
1282            Self {
1283                data_fn: dummy.inner,
1284                status: dummy.status,
1285                headers: dummy.headers,
1286                rate_limits: dummy.rate_limits,
1287            }
1288        }
1289    }
1290
1291    struct MockAccountApiClient {
1292        force_error: bool,
1293    }
1294
1295    #[async_trait]
1296    impl AccountApi for MockAccountApiClient {
1297        async fn account_commission(
1298            &self,
1299            _params: AccountCommissionParams,
1300        ) -> anyhow::Result<RestApiResponse<models::AccountCommissionResponse>> {
1301            if self.force_error {
1302                return Err(ConnectorError::ConnectorClientError {
1303                    msg: "ResponseError".to_string(),
1304                    code: None,
1305                }
1306                .into());
1307            }
1308
1309            let resp_json: Value = serde_json::from_str(r#"{"symbol":"BTCUSDT","standardCommission":{"maker":"0.00000010","taker":"0.00000020","buyer":"0.00000030","seller":"0.00000040"},"specialCommission":{"maker":"0.01000000","taker":"0.02000000","buyer":"0.03000000","seller":"0.04000000"},"taxCommission":{"maker":"0.00000112","taker":"0.00000114","buyer":"0.00000118","seller":"0.00000116"},"discount":{"enabledForAccount":true,"enabledForSymbol":true,"discountAsset":"BNB","discount":"0.75000000"}}"#).unwrap();
1310            let dummy_response: models::AccountCommissionResponse =
1311                serde_json::from_value(resp_json.clone())
1312                    .expect("should parse into models::AccountCommissionResponse");
1313
1314            let dummy = DummyRestApiResponse {
1315                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1316                status: 200,
1317                headers: HashMap::new(),
1318                rate_limits: None,
1319            };
1320
1321            Ok(dummy.into())
1322        }
1323
1324        async fn all_order_list(
1325            &self,
1326            _params: AllOrderListParams,
1327        ) -> anyhow::Result<RestApiResponse<Vec<models::AllOrderListResponseInner>>> {
1328            if self.force_error {
1329                return Err(ConnectorError::ConnectorClientError {
1330                    msg: "ResponseError".to_string(),
1331                    code: None,
1332                }
1333                .into());
1334            }
1335
1336            let resp_json: Value = serde_json::from_str(r#"[{"orderListId":29,"contingencyType":"OCO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"amEEAXryFzFwYF1FeRpUoZ","transactionTime":1565245913483,"symbol":"LTCBTC","orders":[{"symbol":"LTCBTC","orderId":5,"clientOrderId":"Jr1h6xirOxgeJOUuYQS7V3"},{"symbol":"LTCBTC","orderId":4,"clientOrderId":"oD7aesZqjEGlZrbtRpy5zB"}]},{"orderListId":28,"contingencyType":"OCO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"hG7hFNxJV6cZy3Ze4AUT4d","transactionTime":1565245913407,"symbol":"LTCBTC","orders":[{"symbol":"LTCBTC","orderId":2,"clientOrderId":"j6lFOfbmFMRjTYA7rRJ0LP"},{"symbol":"LTCBTC","orderId":3,"clientOrderId":"z0KCjOdditiLS5ekAFtK81"}]}]"#).unwrap();
1337            let dummy_response: Vec<models::AllOrderListResponseInner> =
1338                serde_json::from_value(resp_json.clone())
1339                    .expect("should parse into Vec<models::AllOrderListResponseInner>");
1340
1341            let dummy = DummyRestApiResponse {
1342                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1343                status: 200,
1344                headers: HashMap::new(),
1345                rate_limits: None,
1346            };
1347
1348            Ok(dummy.into())
1349        }
1350
1351        async fn all_orders(
1352            &self,
1353            _params: AllOrdersParams,
1354        ) -> anyhow::Result<RestApiResponse<Vec<models::AllOrdersResponseInner>>> {
1355            if self.force_error {
1356                return Err(ConnectorError::ConnectorClientError {
1357                    msg: "ResponseError".to_string(),
1358                    code: None,
1359                }
1360                .into());
1361            }
1362
1363            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"LTCBTC","orderId":1,"orderListId":-1,"clientOrderId":"myOrder1","price":"0.1","origQty":"1.0","executedQty":"0.0","cummulativeQuoteQty":"0.0","status":"NEW","timeInForce":"GTC","type":"LIMIT","side":"BUY","stopPrice":"0.0","icebergQty":"0.0","time":1499827319559,"updateTime":1499827319559,"isWorking":true,"origQuoteOrderQty":"0.000000","workingTime":1499827319559,"selfTradePreventionMode":"NONE"}]"#).unwrap();
1364            let dummy_response: Vec<models::AllOrdersResponseInner> =
1365                serde_json::from_value(resp_json.clone())
1366                    .expect("should parse into Vec<models::AllOrdersResponseInner>");
1367
1368            let dummy = DummyRestApiResponse {
1369                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1370                status: 200,
1371                headers: HashMap::new(),
1372                rate_limits: None,
1373            };
1374
1375            Ok(dummy.into())
1376        }
1377
1378        async fn get_account(
1379            &self,
1380            _params: GetAccountParams,
1381        ) -> anyhow::Result<RestApiResponse<models::GetAccountResponse>> {
1382            if self.force_error {
1383                return Err(ConnectorError::ConnectorClientError {
1384                    msg: "ResponseError".to_string(),
1385                    code: None,
1386                }
1387                .into());
1388            }
1389
1390            let resp_json: Value = serde_json::from_str(r#"{"makerCommission":15,"takerCommission":15,"buyerCommission":0,"sellerCommission":0,"commissionRates":{"maker":"0.00150000","taker":"0.00150000","buyer":"0.00000000","seller":"0.00000000"},"canTrade":true,"canWithdraw":true,"canDeposit":true,"brokered":false,"requireSelfTradePrevention":false,"preventSor":false,"updateTime":123456789,"accountType":"SPOT","balances":[{"asset":"LTC","free":"4763368.68006011","locked":"0.00000000"},{"asset":"BTC","free":"4723846.89208129","locked":"0.00000000"}],"permissions":["SPOT"],"uid":354937868}"#).unwrap();
1391            let dummy_response: models::GetAccountResponse =
1392                serde_json::from_value(resp_json.clone())
1393                    .expect("should parse into models::GetAccountResponse");
1394
1395            let dummy = DummyRestApiResponse {
1396                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1397                status: 200,
1398                headers: HashMap::new(),
1399                rate_limits: None,
1400            };
1401
1402            Ok(dummy.into())
1403        }
1404
1405        async fn get_open_orders(
1406            &self,
1407            _params: GetOpenOrdersParams,
1408        ) -> anyhow::Result<RestApiResponse<Vec<models::AllOrdersResponseInner>>> {
1409            if self.force_error {
1410                return Err(ConnectorError::ConnectorClientError {
1411                    msg: "ResponseError".to_string(),
1412                    code: None,
1413                }
1414                .into());
1415            }
1416
1417            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"LTCBTC","orderId":1,"orderListId":-1,"clientOrderId":"myOrder1","price":"0.1","origQty":"1.0","executedQty":"0.0","cummulativeQuoteQty":"0.0","status":"NEW","timeInForce":"GTC","type":"LIMIT","side":"BUY","stopPrice":"0.0","icebergQty":"0.0","time":1499827319559,"updateTime":1499827319559,"isWorking":true,"origQuoteOrderQty":"0.000000","workingTime":1499827319559,"selfTradePreventionMode":"NONE"}]"#).unwrap();
1418            let dummy_response: Vec<models::AllOrdersResponseInner> =
1419                serde_json::from_value(resp_json.clone())
1420                    .expect("should parse into Vec<models::AllOrdersResponseInner>");
1421
1422            let dummy = DummyRestApiResponse {
1423                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1424                status: 200,
1425                headers: HashMap::new(),
1426                rate_limits: None,
1427            };
1428
1429            Ok(dummy.into())
1430        }
1431
1432        async fn get_order(
1433            &self,
1434            _params: GetOrderParams,
1435        ) -> anyhow::Result<RestApiResponse<models::GetOrderResponse>> {
1436            if self.force_error {
1437                return Err(ConnectorError::ConnectorClientError {
1438                    msg: "ResponseError".to_string(),
1439                    code: None,
1440                }
1441                .into());
1442            }
1443
1444            let resp_json: Value = serde_json::from_str(r#"{"symbol":"LTCBTC","orderId":1,"orderListId":-1,"clientOrderId":"myOrder1","price":"0.1","origQty":"1.0","executedQty":"0.0","cummulativeQuoteQty":"0.0","status":"NEW","timeInForce":"GTC","type":"LIMIT","side":"BUY","stopPrice":"0.0","icebergQty":"0.0","time":1499827319559,"updateTime":1499827319559,"isWorking":true,"workingTime":1499827319559,"origQuoteOrderQty":"0.000000","selfTradePreventionMode":"NONE"}"#).unwrap();
1445            let dummy_response: models::GetOrderResponse =
1446                serde_json::from_value(resp_json.clone())
1447                    .expect("should parse into models::GetOrderResponse");
1448
1449            let dummy = DummyRestApiResponse {
1450                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1451                status: 200,
1452                headers: HashMap::new(),
1453                rate_limits: None,
1454            };
1455
1456            Ok(dummy.into())
1457        }
1458
1459        async fn get_order_list(
1460            &self,
1461            _params: GetOrderListParams,
1462        ) -> anyhow::Result<RestApiResponse<models::GetOrderListResponse>> {
1463            if self.force_error {
1464                return Err(ConnectorError::ConnectorClientError {
1465                    msg: "ResponseError".to_string(),
1466                    code: None,
1467                }
1468                .into());
1469            }
1470
1471            let resp_json: Value = serde_json::from_str(r#"{"orderListId":27,"contingencyType":"OCO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"h2USkA5YQpaXHPIrkd96xE","transactionTime":1565245656253,"symbol":"LTCBTC","orders":[{"symbol":"LTCBTC","orderId":5,"clientOrderId":"ARzZ9I00CPM8i3NhmU9Ega"},{"symbol":"LTCBTC","orderId":4,"clientOrderId":"qD1gy3kc3Gx0rihm9Y3xwS"}]}"#).unwrap();
1472            let dummy_response: models::GetOrderListResponse =
1473                serde_json::from_value(resp_json.clone())
1474                    .expect("should parse into models::GetOrderListResponse");
1475
1476            let dummy = DummyRestApiResponse {
1477                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1478                status: 200,
1479                headers: HashMap::new(),
1480                rate_limits: None,
1481            };
1482
1483            Ok(dummy.into())
1484        }
1485
1486        async fn my_allocations(
1487            &self,
1488            _params: MyAllocationsParams,
1489        ) -> anyhow::Result<RestApiResponse<Vec<models::MyAllocationsResponseInner>>> {
1490            if self.force_error {
1491                return Err(ConnectorError::ConnectorClientError {
1492                    msg: "ResponseError".to_string(),
1493                    code: None,
1494                }
1495                .into());
1496            }
1497
1498            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"BTCUSDT","allocationId":0,"allocationType":"SOR","orderId":1,"orderListId":-1,"price":"1.00000000","qty":"5.00000000","quoteQty":"5.00000000","commission":"0.00000000","commissionAsset":"BTC","time":1687506878118,"isBuyer":true,"isMaker":false,"isAllocator":false}]"#).unwrap();
1499            let dummy_response: Vec<models::MyAllocationsResponseInner> =
1500                serde_json::from_value(resp_json.clone())
1501                    .expect("should parse into Vec<models::MyAllocationsResponseInner>");
1502
1503            let dummy = DummyRestApiResponse {
1504                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1505                status: 200,
1506                headers: HashMap::new(),
1507                rate_limits: None,
1508            };
1509
1510            Ok(dummy.into())
1511        }
1512
1513        async fn my_filters(
1514            &self,
1515            _params: MyFiltersParams,
1516        ) -> anyhow::Result<RestApiResponse<models::MyFiltersResponse>> {
1517            if self.force_error {
1518                return Err(ConnectorError::ConnectorClientError {
1519                    msg: "ResponseError".to_string(),
1520                    code: None,
1521                }
1522                .into());
1523            }
1524
1525            let resp_json: Value = serde_json::from_str(r#"{"exchangeFilters":[{"filterType":"EXCHANGE_MAX_NUM_ORDERS","maxNumOrders":1000}],"symbolFilters":[{"filterType":"MAX_NUM_ORDER_LISTS","maxNumOrderLists":20}],"assetFilters":[{"filterType":"MAX_ASSET","asset":"JPY","limit":"1000000.00000000"}],"rateLimits":[{"rateLimitType":"REQUEST_WEIGHT","interval":"MINUTE","intervalNum":1,"limit":6000},{"rateLimitType":"ORDERS","interval":"DAY","intervalNum":1,"limit":160000},{"rateLimitType":"RAW_REQUESTS","interval":"MINUTE","intervalNum":5,"limit":61000}]}"#).unwrap();
1526            let dummy_response: models::MyFiltersResponse =
1527                serde_json::from_value(resp_json.clone())
1528                    .expect("should parse into models::MyFiltersResponse");
1529
1530            let dummy = DummyRestApiResponse {
1531                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1532                status: 200,
1533                headers: HashMap::new(),
1534                rate_limits: None,
1535            };
1536
1537            Ok(dummy.into())
1538        }
1539
1540        async fn my_prevented_matches(
1541            &self,
1542            _params: MyPreventedMatchesParams,
1543        ) -> anyhow::Result<RestApiResponse<Vec<models::MyPreventedMatchesResponseInner>>> {
1544            if self.force_error {
1545                return Err(ConnectorError::ConnectorClientError {
1546                    msg: "ResponseError".to_string(),
1547                    code: None,
1548                }
1549                .into());
1550            }
1551
1552            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"BTCUSDT","preventedMatchId":1,"takerOrderId":5,"makerSymbol":"BTCUSDT","makerOrderId":3,"tradeGroupId":1,"selfTradePreventionMode":"EXPIRE_MAKER","price":"1.100000","makerPreventedQuantity":"1.300000","transactTime":1669101687094}]"#).unwrap();
1553            let dummy_response: Vec<models::MyPreventedMatchesResponseInner> =
1554                serde_json::from_value(resp_json.clone())
1555                    .expect("should parse into Vec<models::MyPreventedMatchesResponseInner>");
1556
1557            let dummy = DummyRestApiResponse {
1558                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1559                status: 200,
1560                headers: HashMap::new(),
1561                rate_limits: None,
1562            };
1563
1564            Ok(dummy.into())
1565        }
1566
1567        async fn my_trades(
1568            &self,
1569            _params: MyTradesParams,
1570        ) -> anyhow::Result<RestApiResponse<Vec<models::MyTradesResponseInner>>> {
1571            if self.force_error {
1572                return Err(ConnectorError::ConnectorClientError {
1573                    msg: "ResponseError".to_string(),
1574                    code: None,
1575                }
1576                .into());
1577            }
1578
1579            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"BNBBTC","id":28457,"orderId":100234,"orderListId":-1,"price":"4.00000100","qty":"12.00000000","quoteQty":"48.000012","commission":"10.10000000","commissionAsset":"BNB","time":1499865549590,"isBuyer":true,"isMaker":false,"isBestMatch":true}]"#).unwrap();
1580            let dummy_response: Vec<models::MyTradesResponseInner> =
1581                serde_json::from_value(resp_json.clone())
1582                    .expect("should parse into Vec<models::MyTradesResponseInner>");
1583
1584            let dummy = DummyRestApiResponse {
1585                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1586                status: 200,
1587                headers: HashMap::new(),
1588                rate_limits: None,
1589            };
1590
1591            Ok(dummy.into())
1592        }
1593
1594        async fn open_order_list(
1595            &self,
1596            _params: OpenOrderListParams,
1597        ) -> anyhow::Result<RestApiResponse<Vec<models::OpenOrderListResponseInner>>> {
1598            if self.force_error {
1599                return Err(ConnectorError::ConnectorClientError {
1600                    msg: "ResponseError".to_string(),
1601                    code: None,
1602                }
1603                .into());
1604            }
1605
1606            let resp_json: Value = serde_json::from_str(r#"[{"orderListId":31,"contingencyType":"OCO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"wuB13fmulKj3YjdqWEcsnp","transactionTime":1565246080644,"symbol":"LTCBTC","orders":[{"symbol":"LTCBTC","orderId":5,"clientOrderId":"Cv1SnyPD3qhqpbjpYEHbd2"},{"symbol":"LTCBTC","orderId":4,"clientOrderId":"r3EH2N76dHfLoSZWIUw1bT"}]}]"#).unwrap();
1607            let dummy_response: Vec<models::OpenOrderListResponseInner> =
1608                serde_json::from_value(resp_json.clone())
1609                    .expect("should parse into Vec<models::OpenOrderListResponseInner>");
1610
1611            let dummy = DummyRestApiResponse {
1612                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1613                status: 200,
1614                headers: HashMap::new(),
1615                rate_limits: None,
1616            };
1617
1618            Ok(dummy.into())
1619        }
1620
1621        async fn order_amendments(
1622            &self,
1623            _params: OrderAmendmentsParams,
1624        ) -> anyhow::Result<RestApiResponse<Vec<models::OrderAmendmentsResponseInner>>> {
1625            if self.force_error {
1626                return Err(ConnectorError::ConnectorClientError {
1627                    msg: "ResponseError".to_string(),
1628                    code: None,
1629                }
1630                .into());
1631            }
1632
1633            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"BTCUSDT","orderId":9,"executionId":22,"origClientOrderId":"W0fJ9fiLKHOJutovPK3oJp","newClientOrderId":"UQ1Np3bmQ71jJzsSDW9Vpi","origQty":"5.00000000","newQty":"4.00000000","time":1741669661670},{"symbol":"BTCUDST","orderId":9,"executionId":25,"origClientOrderId":"UQ1Np3bmQ71jJzsSDW9Vpi","newClientOrderId":"5uS0r35ohuQyDlCzZuYXq2","origQty":"4.00000000","newQty":"3.00000000","time":1741672924895}]"#).unwrap();
1634            let dummy_response: Vec<models::OrderAmendmentsResponseInner> =
1635                serde_json::from_value(resp_json.clone())
1636                    .expect("should parse into Vec<models::OrderAmendmentsResponseInner>");
1637
1638            let dummy = DummyRestApiResponse {
1639                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1640                status: 200,
1641                headers: HashMap::new(),
1642                rate_limits: None,
1643            };
1644
1645            Ok(dummy.into())
1646        }
1647
1648        async fn rate_limit_order(
1649            &self,
1650            _params: RateLimitOrderParams,
1651        ) -> anyhow::Result<RestApiResponse<Vec<models::RateLimitOrderResponseInner>>> {
1652            if self.force_error {
1653                return Err(ConnectorError::ConnectorClientError {
1654                    msg: "ResponseError".to_string(),
1655                    code: None,
1656                }
1657                .into());
1658            }
1659
1660            let resp_json: Value = serde_json::from_str(r#"[{"rateLimitType":"ORDERS","interval":"SECOND","intervalNum":10,"limit":50,"count":0},{"rateLimitType":"ORDERS","interval":"DAY","intervalNum":1,"limit":160000,"count":0}]"#).unwrap();
1661            let dummy_response: Vec<models::RateLimitOrderResponseInner> =
1662                serde_json::from_value(resp_json.clone())
1663                    .expect("should parse into Vec<models::RateLimitOrderResponseInner>");
1664
1665            let dummy = DummyRestApiResponse {
1666                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1667                status: 200,
1668                headers: HashMap::new(),
1669                rate_limits: None,
1670            };
1671
1672            Ok(dummy.into())
1673        }
1674    }
1675
1676    #[test]
1677    fn account_commission_required_params_success() {
1678        TOKIO_SHARED_RT.block_on(async {
1679            let client = MockAccountApiClient { force_error: false };
1680
1681            let params = AccountCommissionParams::builder("BNBUSDT".to_string()).build().unwrap();
1682
1683            let resp_json: Value = serde_json::from_str(r#"{"symbol":"BTCUSDT","standardCommission":{"maker":"0.00000010","taker":"0.00000020","buyer":"0.00000030","seller":"0.00000040"},"specialCommission":{"maker":"0.01000000","taker":"0.02000000","buyer":"0.03000000","seller":"0.04000000"},"taxCommission":{"maker":"0.00000112","taker":"0.00000114","buyer":"0.00000118","seller":"0.00000116"},"discount":{"enabledForAccount":true,"enabledForSymbol":true,"discountAsset":"BNB","discount":"0.75000000"}}"#).unwrap();
1684            let expected_response : models::AccountCommissionResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::AccountCommissionResponse");
1685
1686            let resp = client.account_commission(params).await.expect("Expected a response");
1687            let data_future = resp.data();
1688            let actual_response = data_future.await.unwrap();
1689            assert_eq!(actual_response, expected_response);
1690        });
1691    }
1692
1693    #[test]
1694    fn account_commission_optional_params_success() {
1695        TOKIO_SHARED_RT.block_on(async {
1696            let client = MockAccountApiClient { force_error: false };
1697
1698            let params = AccountCommissionParams::builder("BNBUSDT".to_string()).build().unwrap();
1699
1700            let resp_json: Value = serde_json::from_str(r#"{"symbol":"BTCUSDT","standardCommission":{"maker":"0.00000010","taker":"0.00000020","buyer":"0.00000030","seller":"0.00000040"},"specialCommission":{"maker":"0.01000000","taker":"0.02000000","buyer":"0.03000000","seller":"0.04000000"},"taxCommission":{"maker":"0.00000112","taker":"0.00000114","buyer":"0.00000118","seller":"0.00000116"},"discount":{"enabledForAccount":true,"enabledForSymbol":true,"discountAsset":"BNB","discount":"0.75000000"}}"#).unwrap();
1701            let expected_response : models::AccountCommissionResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::AccountCommissionResponse");
1702
1703            let resp = client.account_commission(params).await.expect("Expected a response");
1704            let data_future = resp.data();
1705            let actual_response = data_future.await.unwrap();
1706            assert_eq!(actual_response, expected_response);
1707        });
1708    }
1709
1710    #[test]
1711    fn account_commission_response_error() {
1712        TOKIO_SHARED_RT.block_on(async {
1713            let client = MockAccountApiClient { force_error: true };
1714
1715            let params = AccountCommissionParams::builder("BNBUSDT".to_string())
1716                .build()
1717                .unwrap();
1718
1719            match client.account_commission(params).await {
1720                Ok(_) => panic!("Expected an error"),
1721                Err(err) => {
1722                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1723                }
1724            }
1725        });
1726    }
1727
1728    #[test]
1729    fn all_order_list_required_params_success() {
1730        TOKIO_SHARED_RT.block_on(async {
1731            let client = MockAccountApiClient { force_error: false };
1732
1733            let params = AllOrderListParams::builder().build().unwrap();
1734
1735            let resp_json: Value = serde_json::from_str(r#"[{"orderListId":29,"contingencyType":"OCO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"amEEAXryFzFwYF1FeRpUoZ","transactionTime":1565245913483,"symbol":"LTCBTC","orders":[{"symbol":"LTCBTC","orderId":5,"clientOrderId":"Jr1h6xirOxgeJOUuYQS7V3"},{"symbol":"LTCBTC","orderId":4,"clientOrderId":"oD7aesZqjEGlZrbtRpy5zB"}]},{"orderListId":28,"contingencyType":"OCO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"hG7hFNxJV6cZy3Ze4AUT4d","transactionTime":1565245913407,"symbol":"LTCBTC","orders":[{"symbol":"LTCBTC","orderId":2,"clientOrderId":"j6lFOfbmFMRjTYA7rRJ0LP"},{"symbol":"LTCBTC","orderId":3,"clientOrderId":"z0KCjOdditiLS5ekAFtK81"}]}]"#).unwrap();
1736            let expected_response : Vec<models::AllOrderListResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::AllOrderListResponseInner>");
1737
1738            let resp = client.all_order_list(params).await.expect("Expected a response");
1739            let data_future = resp.data();
1740            let actual_response = data_future.await.unwrap();
1741            assert_eq!(actual_response, expected_response);
1742        });
1743    }
1744
1745    #[test]
1746    fn all_order_list_optional_params_success() {
1747        TOKIO_SHARED_RT.block_on(async {
1748            let client = MockAccountApiClient { force_error: false };
1749
1750            let params = AllOrderListParams::builder().from_id(1).start_time(1735693200000).end_time(1735693200000).limit(500).recv_window(dec!(5000.0)).build().unwrap();
1751
1752            let resp_json: Value = serde_json::from_str(r#"[{"orderListId":29,"contingencyType":"OCO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"amEEAXryFzFwYF1FeRpUoZ","transactionTime":1565245913483,"symbol":"LTCBTC","orders":[{"symbol":"LTCBTC","orderId":5,"clientOrderId":"Jr1h6xirOxgeJOUuYQS7V3"},{"symbol":"LTCBTC","orderId":4,"clientOrderId":"oD7aesZqjEGlZrbtRpy5zB"}]},{"orderListId":28,"contingencyType":"OCO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"hG7hFNxJV6cZy3Ze4AUT4d","transactionTime":1565245913407,"symbol":"LTCBTC","orders":[{"symbol":"LTCBTC","orderId":2,"clientOrderId":"j6lFOfbmFMRjTYA7rRJ0LP"},{"symbol":"LTCBTC","orderId":3,"clientOrderId":"z0KCjOdditiLS5ekAFtK81"}]}]"#).unwrap();
1753            let expected_response : Vec<models::AllOrderListResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::AllOrderListResponseInner>");
1754
1755            let resp = client.all_order_list(params).await.expect("Expected a response");
1756            let data_future = resp.data();
1757            let actual_response = data_future.await.unwrap();
1758            assert_eq!(actual_response, expected_response);
1759        });
1760    }
1761
1762    #[test]
1763    fn all_order_list_response_error() {
1764        TOKIO_SHARED_RT.block_on(async {
1765            let client = MockAccountApiClient { force_error: true };
1766
1767            let params = AllOrderListParams::builder().build().unwrap();
1768
1769            match client.all_order_list(params).await {
1770                Ok(_) => panic!("Expected an error"),
1771                Err(err) => {
1772                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1773                }
1774            }
1775        });
1776    }
1777
1778    #[test]
1779    fn all_orders_required_params_success() {
1780        TOKIO_SHARED_RT.block_on(async {
1781            let client = MockAccountApiClient { force_error: false };
1782
1783            let params = AllOrdersParams::builder("BNBUSDT".to_string(),).build().unwrap();
1784
1785            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"LTCBTC","orderId":1,"orderListId":-1,"clientOrderId":"myOrder1","price":"0.1","origQty":"1.0","executedQty":"0.0","cummulativeQuoteQty":"0.0","status":"NEW","timeInForce":"GTC","type":"LIMIT","side":"BUY","stopPrice":"0.0","icebergQty":"0.0","time":1499827319559,"updateTime":1499827319559,"isWorking":true,"origQuoteOrderQty":"0.000000","workingTime":1499827319559,"selfTradePreventionMode":"NONE"}]"#).unwrap();
1786            let expected_response : Vec<models::AllOrdersResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::AllOrdersResponseInner>");
1787
1788            let resp = client.all_orders(params).await.expect("Expected a response");
1789            let data_future = resp.data();
1790            let actual_response = data_future.await.unwrap();
1791            assert_eq!(actual_response, expected_response);
1792        });
1793    }
1794
1795    #[test]
1796    fn all_orders_optional_params_success() {
1797        TOKIO_SHARED_RT.block_on(async {
1798            let client = MockAccountApiClient { force_error: false };
1799
1800            let params = AllOrdersParams::builder("BNBUSDT".to_string(),).order_id(1).start_time(1735693200000).end_time(1735693200000).limit(500).recv_window(dec!(5000.0)).build().unwrap();
1801
1802            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"LTCBTC","orderId":1,"orderListId":-1,"clientOrderId":"myOrder1","price":"0.1","origQty":"1.0","executedQty":"0.0","cummulativeQuoteQty":"0.0","status":"NEW","timeInForce":"GTC","type":"LIMIT","side":"BUY","stopPrice":"0.0","icebergQty":"0.0","time":1499827319559,"updateTime":1499827319559,"isWorking":true,"origQuoteOrderQty":"0.000000","workingTime":1499827319559,"selfTradePreventionMode":"NONE"}]"#).unwrap();
1803            let expected_response : Vec<models::AllOrdersResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::AllOrdersResponseInner>");
1804
1805            let resp = client.all_orders(params).await.expect("Expected a response");
1806            let data_future = resp.data();
1807            let actual_response = data_future.await.unwrap();
1808            assert_eq!(actual_response, expected_response);
1809        });
1810    }
1811
1812    #[test]
1813    fn all_orders_response_error() {
1814        TOKIO_SHARED_RT.block_on(async {
1815            let client = MockAccountApiClient { force_error: true };
1816
1817            let params = AllOrdersParams::builder("BNBUSDT".to_string())
1818                .build()
1819                .unwrap();
1820
1821            match client.all_orders(params).await {
1822                Ok(_) => panic!("Expected an error"),
1823                Err(err) => {
1824                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1825                }
1826            }
1827        });
1828    }
1829
1830    #[test]
1831    fn get_account_required_params_success() {
1832        TOKIO_SHARED_RT.block_on(async {
1833            let client = MockAccountApiClient { force_error: false };
1834
1835            let params = GetAccountParams::builder().build().unwrap();
1836
1837            let resp_json: Value = serde_json::from_str(r#"{"makerCommission":15,"takerCommission":15,"buyerCommission":0,"sellerCommission":0,"commissionRates":{"maker":"0.00150000","taker":"0.00150000","buyer":"0.00000000","seller":"0.00000000"},"canTrade":true,"canWithdraw":true,"canDeposit":true,"brokered":false,"requireSelfTradePrevention":false,"preventSor":false,"updateTime":123456789,"accountType":"SPOT","balances":[{"asset":"LTC","free":"4763368.68006011","locked":"0.00000000"},{"asset":"BTC","free":"4723846.89208129","locked":"0.00000000"}],"permissions":["SPOT"],"uid":354937868}"#).unwrap();
1838            let expected_response : models::GetAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetAccountResponse");
1839
1840            let resp = client.get_account(params).await.expect("Expected a response");
1841            let data_future = resp.data();
1842            let actual_response = data_future.await.unwrap();
1843            assert_eq!(actual_response, expected_response);
1844        });
1845    }
1846
1847    #[test]
1848    fn get_account_optional_params_success() {
1849        TOKIO_SHARED_RT.block_on(async {
1850            let client = MockAccountApiClient { force_error: false };
1851
1852            let params = GetAccountParams::builder().omit_zero_balances(false).recv_window(dec!(5000.0)).build().unwrap();
1853
1854            let resp_json: Value = serde_json::from_str(r#"{"makerCommission":15,"takerCommission":15,"buyerCommission":0,"sellerCommission":0,"commissionRates":{"maker":"0.00150000","taker":"0.00150000","buyer":"0.00000000","seller":"0.00000000"},"canTrade":true,"canWithdraw":true,"canDeposit":true,"brokered":false,"requireSelfTradePrevention":false,"preventSor":false,"updateTime":123456789,"accountType":"SPOT","balances":[{"asset":"LTC","free":"4763368.68006011","locked":"0.00000000"},{"asset":"BTC","free":"4723846.89208129","locked":"0.00000000"}],"permissions":["SPOT"],"uid":354937868}"#).unwrap();
1855            let expected_response : models::GetAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetAccountResponse");
1856
1857            let resp = client.get_account(params).await.expect("Expected a response");
1858            let data_future = resp.data();
1859            let actual_response = data_future.await.unwrap();
1860            assert_eq!(actual_response, expected_response);
1861        });
1862    }
1863
1864    #[test]
1865    fn get_account_response_error() {
1866        TOKIO_SHARED_RT.block_on(async {
1867            let client = MockAccountApiClient { force_error: true };
1868
1869            let params = GetAccountParams::builder().build().unwrap();
1870
1871            match client.get_account(params).await {
1872                Ok(_) => panic!("Expected an error"),
1873                Err(err) => {
1874                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1875                }
1876            }
1877        });
1878    }
1879
1880    #[test]
1881    fn get_open_orders_required_params_success() {
1882        TOKIO_SHARED_RT.block_on(async {
1883            let client = MockAccountApiClient { force_error: false };
1884
1885            let params = GetOpenOrdersParams::builder().build().unwrap();
1886
1887            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"LTCBTC","orderId":1,"orderListId":-1,"clientOrderId":"myOrder1","price":"0.1","origQty":"1.0","executedQty":"0.0","cummulativeQuoteQty":"0.0","status":"NEW","timeInForce":"GTC","type":"LIMIT","side":"BUY","stopPrice":"0.0","icebergQty":"0.0","time":1499827319559,"updateTime":1499827319559,"isWorking":true,"origQuoteOrderQty":"0.000000","workingTime":1499827319559,"selfTradePreventionMode":"NONE"}]"#).unwrap();
1888            let expected_response : Vec<models::AllOrdersResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::AllOrdersResponseInner>");
1889
1890            let resp = client.get_open_orders(params).await.expect("Expected a response");
1891            let data_future = resp.data();
1892            let actual_response = data_future.await.unwrap();
1893            assert_eq!(actual_response, expected_response);
1894        });
1895    }
1896
1897    #[test]
1898    fn get_open_orders_optional_params_success() {
1899        TOKIO_SHARED_RT.block_on(async {
1900            let client = MockAccountApiClient { force_error: false };
1901
1902            let params = GetOpenOrdersParams::builder().symbol("BNBUSDT".to_string()).recv_window(dec!(5000.0)).build().unwrap();
1903
1904            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"LTCBTC","orderId":1,"orderListId":-1,"clientOrderId":"myOrder1","price":"0.1","origQty":"1.0","executedQty":"0.0","cummulativeQuoteQty":"0.0","status":"NEW","timeInForce":"GTC","type":"LIMIT","side":"BUY","stopPrice":"0.0","icebergQty":"0.0","time":1499827319559,"updateTime":1499827319559,"isWorking":true,"origQuoteOrderQty":"0.000000","workingTime":1499827319559,"selfTradePreventionMode":"NONE"}]"#).unwrap();
1905            let expected_response : Vec<models::AllOrdersResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::AllOrdersResponseInner>");
1906
1907            let resp = client.get_open_orders(params).await.expect("Expected a response");
1908            let data_future = resp.data();
1909            let actual_response = data_future.await.unwrap();
1910            assert_eq!(actual_response, expected_response);
1911        });
1912    }
1913
1914    #[test]
1915    fn get_open_orders_response_error() {
1916        TOKIO_SHARED_RT.block_on(async {
1917            let client = MockAccountApiClient { force_error: true };
1918
1919            let params = GetOpenOrdersParams::builder().build().unwrap();
1920
1921            match client.get_open_orders(params).await {
1922                Ok(_) => panic!("Expected an error"),
1923                Err(err) => {
1924                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1925                }
1926            }
1927        });
1928    }
1929
1930    #[test]
1931    fn get_order_required_params_success() {
1932        TOKIO_SHARED_RT.block_on(async {
1933            let client = MockAccountApiClient { force_error: false };
1934
1935            let params = GetOrderParams::builder("BNBUSDT".to_string(),).build().unwrap();
1936
1937            let resp_json: Value = serde_json::from_str(r#"{"symbol":"LTCBTC","orderId":1,"orderListId":-1,"clientOrderId":"myOrder1","price":"0.1","origQty":"1.0","executedQty":"0.0","cummulativeQuoteQty":"0.0","status":"NEW","timeInForce":"GTC","type":"LIMIT","side":"BUY","stopPrice":"0.0","icebergQty":"0.0","time":1499827319559,"updateTime":1499827319559,"isWorking":true,"workingTime":1499827319559,"origQuoteOrderQty":"0.000000","selfTradePreventionMode":"NONE"}"#).unwrap();
1938            let expected_response : models::GetOrderResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetOrderResponse");
1939
1940            let resp = client.get_order(params).await.expect("Expected a response");
1941            let data_future = resp.data();
1942            let actual_response = data_future.await.unwrap();
1943            assert_eq!(actual_response, expected_response);
1944        });
1945    }
1946
1947    #[test]
1948    fn get_order_optional_params_success() {
1949        TOKIO_SHARED_RT.block_on(async {
1950            let client = MockAccountApiClient { force_error: false };
1951
1952            let params = GetOrderParams::builder("BNBUSDT".to_string(),).order_id(1).orig_client_order_id("orig_client_order_id_example".to_string()).recv_window(dec!(5000.0)).build().unwrap();
1953
1954            let resp_json: Value = serde_json::from_str(r#"{"symbol":"LTCBTC","orderId":1,"orderListId":-1,"clientOrderId":"myOrder1","price":"0.1","origQty":"1.0","executedQty":"0.0","cummulativeQuoteQty":"0.0","status":"NEW","timeInForce":"GTC","type":"LIMIT","side":"BUY","stopPrice":"0.0","icebergQty":"0.0","time":1499827319559,"updateTime":1499827319559,"isWorking":true,"workingTime":1499827319559,"origQuoteOrderQty":"0.000000","selfTradePreventionMode":"NONE"}"#).unwrap();
1955            let expected_response : models::GetOrderResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetOrderResponse");
1956
1957            let resp = client.get_order(params).await.expect("Expected a response");
1958            let data_future = resp.data();
1959            let actual_response = data_future.await.unwrap();
1960            assert_eq!(actual_response, expected_response);
1961        });
1962    }
1963
1964    #[test]
1965    fn get_order_response_error() {
1966        TOKIO_SHARED_RT.block_on(async {
1967            let client = MockAccountApiClient { force_error: true };
1968
1969            let params = GetOrderParams::builder("BNBUSDT".to_string())
1970                .build()
1971                .unwrap();
1972
1973            match client.get_order(params).await {
1974                Ok(_) => panic!("Expected an error"),
1975                Err(err) => {
1976                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1977                }
1978            }
1979        });
1980    }
1981
1982    #[test]
1983    fn get_order_list_required_params_success() {
1984        TOKIO_SHARED_RT.block_on(async {
1985            let client = MockAccountApiClient { force_error: false };
1986
1987            let params = GetOrderListParams::builder().build().unwrap();
1988
1989            let resp_json: Value = serde_json::from_str(r#"{"orderListId":27,"contingencyType":"OCO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"h2USkA5YQpaXHPIrkd96xE","transactionTime":1565245656253,"symbol":"LTCBTC","orders":[{"symbol":"LTCBTC","orderId":5,"clientOrderId":"ARzZ9I00CPM8i3NhmU9Ega"},{"symbol":"LTCBTC","orderId":4,"clientOrderId":"qD1gy3kc3Gx0rihm9Y3xwS"}]}"#).unwrap();
1990            let expected_response : models::GetOrderListResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetOrderListResponse");
1991
1992            let resp = client.get_order_list(params).await.expect("Expected a response");
1993            let data_future = resp.data();
1994            let actual_response = data_future.await.unwrap();
1995            assert_eq!(actual_response, expected_response);
1996        });
1997    }
1998
1999    #[test]
2000    fn get_order_list_optional_params_success() {
2001        TOKIO_SHARED_RT.block_on(async {
2002            let client = MockAccountApiClient { force_error: false };
2003
2004            let params = GetOrderListParams::builder().order_list_id(1).orig_client_order_id("orig_client_order_id_example".to_string()).recv_window(dec!(5000.0)).build().unwrap();
2005
2006            let resp_json: Value = serde_json::from_str(r#"{"orderListId":27,"contingencyType":"OCO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"h2USkA5YQpaXHPIrkd96xE","transactionTime":1565245656253,"symbol":"LTCBTC","orders":[{"symbol":"LTCBTC","orderId":5,"clientOrderId":"ARzZ9I00CPM8i3NhmU9Ega"},{"symbol":"LTCBTC","orderId":4,"clientOrderId":"qD1gy3kc3Gx0rihm9Y3xwS"}]}"#).unwrap();
2007            let expected_response : models::GetOrderListResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetOrderListResponse");
2008
2009            let resp = client.get_order_list(params).await.expect("Expected a response");
2010            let data_future = resp.data();
2011            let actual_response = data_future.await.unwrap();
2012            assert_eq!(actual_response, expected_response);
2013        });
2014    }
2015
2016    #[test]
2017    fn get_order_list_response_error() {
2018        TOKIO_SHARED_RT.block_on(async {
2019            let client = MockAccountApiClient { force_error: true };
2020
2021            let params = GetOrderListParams::builder().build().unwrap();
2022
2023            match client.get_order_list(params).await {
2024                Ok(_) => panic!("Expected an error"),
2025                Err(err) => {
2026                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
2027                }
2028            }
2029        });
2030    }
2031
2032    #[test]
2033    fn my_allocations_required_params_success() {
2034        TOKIO_SHARED_RT.block_on(async {
2035            let client = MockAccountApiClient { force_error: false };
2036
2037            let params = MyAllocationsParams::builder("BNBUSDT".to_string(),).build().unwrap();
2038
2039            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"BTCUSDT","allocationId":0,"allocationType":"SOR","orderId":1,"orderListId":-1,"price":"1.00000000","qty":"5.00000000","quoteQty":"5.00000000","commission":"0.00000000","commissionAsset":"BTC","time":1687506878118,"isBuyer":true,"isMaker":false,"isAllocator":false}]"#).unwrap();
2040            let expected_response : Vec<models::MyAllocationsResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::MyAllocationsResponseInner>");
2041
2042            let resp = client.my_allocations(params).await.expect("Expected a response");
2043            let data_future = resp.data();
2044            let actual_response = data_future.await.unwrap();
2045            assert_eq!(actual_response, expected_response);
2046        });
2047    }
2048
2049    #[test]
2050    fn my_allocations_optional_params_success() {
2051        TOKIO_SHARED_RT.block_on(async {
2052            let client = MockAccountApiClient { force_error: false };
2053
2054            let params = MyAllocationsParams::builder("BNBUSDT".to_string(),).start_time(1735693200000).end_time(1735693200000).from_allocation_id(1).limit(500).order_id(1).recv_window(dec!(5000.0)).build().unwrap();
2055
2056            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"BTCUSDT","allocationId":0,"allocationType":"SOR","orderId":1,"orderListId":-1,"price":"1.00000000","qty":"5.00000000","quoteQty":"5.00000000","commission":"0.00000000","commissionAsset":"BTC","time":1687506878118,"isBuyer":true,"isMaker":false,"isAllocator":false}]"#).unwrap();
2057            let expected_response : Vec<models::MyAllocationsResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::MyAllocationsResponseInner>");
2058
2059            let resp = client.my_allocations(params).await.expect("Expected a response");
2060            let data_future = resp.data();
2061            let actual_response = data_future.await.unwrap();
2062            assert_eq!(actual_response, expected_response);
2063        });
2064    }
2065
2066    #[test]
2067    fn my_allocations_response_error() {
2068        TOKIO_SHARED_RT.block_on(async {
2069            let client = MockAccountApiClient { force_error: true };
2070
2071            let params = MyAllocationsParams::builder("BNBUSDT".to_string())
2072                .build()
2073                .unwrap();
2074
2075            match client.my_allocations(params).await {
2076                Ok(_) => panic!("Expected an error"),
2077                Err(err) => {
2078                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
2079                }
2080            }
2081        });
2082    }
2083
2084    #[test]
2085    fn my_filters_required_params_success() {
2086        TOKIO_SHARED_RT.block_on(async {
2087            let client = MockAccountApiClient { force_error: false };
2088
2089            let params = MyFiltersParams::builder("BNBUSDT".to_string(),).build().unwrap();
2090
2091            let resp_json: Value = serde_json::from_str(r#"{"exchangeFilters":[{"filterType":"EXCHANGE_MAX_NUM_ORDERS","maxNumOrders":1000}],"symbolFilters":[{"filterType":"MAX_NUM_ORDER_LISTS","maxNumOrderLists":20}],"assetFilters":[{"filterType":"MAX_ASSET","asset":"JPY","limit":"1000000.00000000"}],"rateLimits":[{"rateLimitType":"REQUEST_WEIGHT","interval":"MINUTE","intervalNum":1,"limit":6000},{"rateLimitType":"ORDERS","interval":"DAY","intervalNum":1,"limit":160000},{"rateLimitType":"RAW_REQUESTS","interval":"MINUTE","intervalNum":5,"limit":61000}]}"#).unwrap();
2092            let expected_response : models::MyFiltersResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::MyFiltersResponse");
2093
2094            let resp = client.my_filters(params).await.expect("Expected a response");
2095            let data_future = resp.data();
2096            let actual_response = data_future.await.unwrap();
2097            assert_eq!(actual_response, expected_response);
2098        });
2099    }
2100
2101    #[test]
2102    fn my_filters_optional_params_success() {
2103        TOKIO_SHARED_RT.block_on(async {
2104            let client = MockAccountApiClient { force_error: false };
2105
2106            let params = MyFiltersParams::builder("BNBUSDT".to_string(),).recv_window(dec!(5000.0)).build().unwrap();
2107
2108            let resp_json: Value = serde_json::from_str(r#"{"exchangeFilters":[{"filterType":"EXCHANGE_MAX_NUM_ORDERS","maxNumOrders":1000}],"symbolFilters":[{"filterType":"MAX_NUM_ORDER_LISTS","maxNumOrderLists":20}],"assetFilters":[{"filterType":"MAX_ASSET","asset":"JPY","limit":"1000000.00000000"}],"rateLimits":[{"rateLimitType":"REQUEST_WEIGHT","interval":"MINUTE","intervalNum":1,"limit":6000},{"rateLimitType":"ORDERS","interval":"DAY","intervalNum":1,"limit":160000},{"rateLimitType":"RAW_REQUESTS","interval":"MINUTE","intervalNum":5,"limit":61000}]}"#).unwrap();
2109            let expected_response : models::MyFiltersResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::MyFiltersResponse");
2110
2111            let resp = client.my_filters(params).await.expect("Expected a response");
2112            let data_future = resp.data();
2113            let actual_response = data_future.await.unwrap();
2114            assert_eq!(actual_response, expected_response);
2115        });
2116    }
2117
2118    #[test]
2119    fn my_filters_response_error() {
2120        TOKIO_SHARED_RT.block_on(async {
2121            let client = MockAccountApiClient { force_error: true };
2122
2123            let params = MyFiltersParams::builder("BNBUSDT".to_string())
2124                .build()
2125                .unwrap();
2126
2127            match client.my_filters(params).await {
2128                Ok(_) => panic!("Expected an error"),
2129                Err(err) => {
2130                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
2131                }
2132            }
2133        });
2134    }
2135
2136    #[test]
2137    fn my_prevented_matches_required_params_success() {
2138        TOKIO_SHARED_RT.block_on(async {
2139            let client = MockAccountApiClient { force_error: false };
2140
2141            let params = MyPreventedMatchesParams::builder("BNBUSDT".to_string(),).build().unwrap();
2142
2143            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"BTCUSDT","preventedMatchId":1,"takerOrderId":5,"makerSymbol":"BTCUSDT","makerOrderId":3,"tradeGroupId":1,"selfTradePreventionMode":"EXPIRE_MAKER","price":"1.100000","makerPreventedQuantity":"1.300000","transactTime":1669101687094}]"#).unwrap();
2144            let expected_response : Vec<models::MyPreventedMatchesResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::MyPreventedMatchesResponseInner>");
2145
2146            let resp = client.my_prevented_matches(params).await.expect("Expected a response");
2147            let data_future = resp.data();
2148            let actual_response = data_future.await.unwrap();
2149            assert_eq!(actual_response, expected_response);
2150        });
2151    }
2152
2153    #[test]
2154    fn my_prevented_matches_optional_params_success() {
2155        TOKIO_SHARED_RT.block_on(async {
2156            let client = MockAccountApiClient { force_error: false };
2157
2158            let params = MyPreventedMatchesParams::builder("BNBUSDT".to_string(),).prevented_match_id(1).order_id(1).from_prevented_match_id(1).limit(500).recv_window(dec!(5000.0)).build().unwrap();
2159
2160            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"BTCUSDT","preventedMatchId":1,"takerOrderId":5,"makerSymbol":"BTCUSDT","makerOrderId":3,"tradeGroupId":1,"selfTradePreventionMode":"EXPIRE_MAKER","price":"1.100000","makerPreventedQuantity":"1.300000","transactTime":1669101687094}]"#).unwrap();
2161            let expected_response : Vec<models::MyPreventedMatchesResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::MyPreventedMatchesResponseInner>");
2162
2163            let resp = client.my_prevented_matches(params).await.expect("Expected a response");
2164            let data_future = resp.data();
2165            let actual_response = data_future.await.unwrap();
2166            assert_eq!(actual_response, expected_response);
2167        });
2168    }
2169
2170    #[test]
2171    fn my_prevented_matches_response_error() {
2172        TOKIO_SHARED_RT.block_on(async {
2173            let client = MockAccountApiClient { force_error: true };
2174
2175            let params = MyPreventedMatchesParams::builder("BNBUSDT".to_string())
2176                .build()
2177                .unwrap();
2178
2179            match client.my_prevented_matches(params).await {
2180                Ok(_) => panic!("Expected an error"),
2181                Err(err) => {
2182                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
2183                }
2184            }
2185        });
2186    }
2187
2188    #[test]
2189    fn my_trades_required_params_success() {
2190        TOKIO_SHARED_RT.block_on(async {
2191            let client = MockAccountApiClient { force_error: false };
2192
2193            let params = MyTradesParams::builder("BNBUSDT".to_string(),).build().unwrap();
2194
2195            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"BNBBTC","id":28457,"orderId":100234,"orderListId":-1,"price":"4.00000100","qty":"12.00000000","quoteQty":"48.000012","commission":"10.10000000","commissionAsset":"BNB","time":1499865549590,"isBuyer":true,"isMaker":false,"isBestMatch":true}]"#).unwrap();
2196            let expected_response : Vec<models::MyTradesResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::MyTradesResponseInner>");
2197
2198            let resp = client.my_trades(params).await.expect("Expected a response");
2199            let data_future = resp.data();
2200            let actual_response = data_future.await.unwrap();
2201            assert_eq!(actual_response, expected_response);
2202        });
2203    }
2204
2205    #[test]
2206    fn my_trades_optional_params_success() {
2207        TOKIO_SHARED_RT.block_on(async {
2208            let client = MockAccountApiClient { force_error: false };
2209
2210            let params = MyTradesParams::builder("BNBUSDT".to_string(),).order_id(1).start_time(1735693200000).end_time(1735693200000).from_id(1).limit(500).recv_window(dec!(5000.0)).build().unwrap();
2211
2212            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"BNBBTC","id":28457,"orderId":100234,"orderListId":-1,"price":"4.00000100","qty":"12.00000000","quoteQty":"48.000012","commission":"10.10000000","commissionAsset":"BNB","time":1499865549590,"isBuyer":true,"isMaker":false,"isBestMatch":true}]"#).unwrap();
2213            let expected_response : Vec<models::MyTradesResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::MyTradesResponseInner>");
2214
2215            let resp = client.my_trades(params).await.expect("Expected a response");
2216            let data_future = resp.data();
2217            let actual_response = data_future.await.unwrap();
2218            assert_eq!(actual_response, expected_response);
2219        });
2220    }
2221
2222    #[test]
2223    fn my_trades_response_error() {
2224        TOKIO_SHARED_RT.block_on(async {
2225            let client = MockAccountApiClient { force_error: true };
2226
2227            let params = MyTradesParams::builder("BNBUSDT".to_string())
2228                .build()
2229                .unwrap();
2230
2231            match client.my_trades(params).await {
2232                Ok(_) => panic!("Expected an error"),
2233                Err(err) => {
2234                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
2235                }
2236            }
2237        });
2238    }
2239
2240    #[test]
2241    fn open_order_list_required_params_success() {
2242        TOKIO_SHARED_RT.block_on(async {
2243            let client = MockAccountApiClient { force_error: false };
2244
2245            let params = OpenOrderListParams::builder().build().unwrap();
2246
2247            let resp_json: Value = serde_json::from_str(r#"[{"orderListId":31,"contingencyType":"OCO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"wuB13fmulKj3YjdqWEcsnp","transactionTime":1565246080644,"symbol":"LTCBTC","orders":[{"symbol":"LTCBTC","orderId":5,"clientOrderId":"Cv1SnyPD3qhqpbjpYEHbd2"},{"symbol":"LTCBTC","orderId":4,"clientOrderId":"r3EH2N76dHfLoSZWIUw1bT"}]}]"#).unwrap();
2248            let expected_response : Vec<models::OpenOrderListResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::OpenOrderListResponseInner>");
2249
2250            let resp = client.open_order_list(params).await.expect("Expected a response");
2251            let data_future = resp.data();
2252            let actual_response = data_future.await.unwrap();
2253            assert_eq!(actual_response, expected_response);
2254        });
2255    }
2256
2257    #[test]
2258    fn open_order_list_optional_params_success() {
2259        TOKIO_SHARED_RT.block_on(async {
2260            let client = MockAccountApiClient { force_error: false };
2261
2262            let params = OpenOrderListParams::builder().recv_window(dec!(5000.0)).build().unwrap();
2263
2264            let resp_json: Value = serde_json::from_str(r#"[{"orderListId":31,"contingencyType":"OCO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"wuB13fmulKj3YjdqWEcsnp","transactionTime":1565246080644,"symbol":"LTCBTC","orders":[{"symbol":"LTCBTC","orderId":5,"clientOrderId":"Cv1SnyPD3qhqpbjpYEHbd2"},{"symbol":"LTCBTC","orderId":4,"clientOrderId":"r3EH2N76dHfLoSZWIUw1bT"}]}]"#).unwrap();
2265            let expected_response : Vec<models::OpenOrderListResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::OpenOrderListResponseInner>");
2266
2267            let resp = client.open_order_list(params).await.expect("Expected a response");
2268            let data_future = resp.data();
2269            let actual_response = data_future.await.unwrap();
2270            assert_eq!(actual_response, expected_response);
2271        });
2272    }
2273
2274    #[test]
2275    fn open_order_list_response_error() {
2276        TOKIO_SHARED_RT.block_on(async {
2277            let client = MockAccountApiClient { force_error: true };
2278
2279            let params = OpenOrderListParams::builder().build().unwrap();
2280
2281            match client.open_order_list(params).await {
2282                Ok(_) => panic!("Expected an error"),
2283                Err(err) => {
2284                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
2285                }
2286            }
2287        });
2288    }
2289
2290    #[test]
2291    fn order_amendments_required_params_success() {
2292        TOKIO_SHARED_RT.block_on(async {
2293            let client = MockAccountApiClient { force_error: false };
2294
2295            let params = OrderAmendmentsParams::builder("BNBUSDT".to_string(),1,).build().unwrap();
2296
2297            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"BTCUSDT","orderId":9,"executionId":22,"origClientOrderId":"W0fJ9fiLKHOJutovPK3oJp","newClientOrderId":"UQ1Np3bmQ71jJzsSDW9Vpi","origQty":"5.00000000","newQty":"4.00000000","time":1741669661670},{"symbol":"BTCUDST","orderId":9,"executionId":25,"origClientOrderId":"UQ1Np3bmQ71jJzsSDW9Vpi","newClientOrderId":"5uS0r35ohuQyDlCzZuYXq2","origQty":"4.00000000","newQty":"3.00000000","time":1741672924895}]"#).unwrap();
2298            let expected_response : Vec<models::OrderAmendmentsResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::OrderAmendmentsResponseInner>");
2299
2300            let resp = client.order_amendments(params).await.expect("Expected a response");
2301            let data_future = resp.data();
2302            let actual_response = data_future.await.unwrap();
2303            assert_eq!(actual_response, expected_response);
2304        });
2305    }
2306
2307    #[test]
2308    fn order_amendments_optional_params_success() {
2309        TOKIO_SHARED_RT.block_on(async {
2310            let client = MockAccountApiClient { force_error: false };
2311
2312            let params = OrderAmendmentsParams::builder("BNBUSDT".to_string(),1,).from_execution_id(1).limit(500).recv_window(dec!(5000.0)).build().unwrap();
2313
2314            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"BTCUSDT","orderId":9,"executionId":22,"origClientOrderId":"W0fJ9fiLKHOJutovPK3oJp","newClientOrderId":"UQ1Np3bmQ71jJzsSDW9Vpi","origQty":"5.00000000","newQty":"4.00000000","time":1741669661670},{"symbol":"BTCUDST","orderId":9,"executionId":25,"origClientOrderId":"UQ1Np3bmQ71jJzsSDW9Vpi","newClientOrderId":"5uS0r35ohuQyDlCzZuYXq2","origQty":"4.00000000","newQty":"3.00000000","time":1741672924895}]"#).unwrap();
2315            let expected_response : Vec<models::OrderAmendmentsResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::OrderAmendmentsResponseInner>");
2316
2317            let resp = client.order_amendments(params).await.expect("Expected a response");
2318            let data_future = resp.data();
2319            let actual_response = data_future.await.unwrap();
2320            assert_eq!(actual_response, expected_response);
2321        });
2322    }
2323
2324    #[test]
2325    fn order_amendments_response_error() {
2326        TOKIO_SHARED_RT.block_on(async {
2327            let client = MockAccountApiClient { force_error: true };
2328
2329            let params = OrderAmendmentsParams::builder("BNBUSDT".to_string(), 1)
2330                .build()
2331                .unwrap();
2332
2333            match client.order_amendments(params).await {
2334                Ok(_) => panic!("Expected an error"),
2335                Err(err) => {
2336                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
2337                }
2338            }
2339        });
2340    }
2341
2342    #[test]
2343    fn rate_limit_order_required_params_success() {
2344        TOKIO_SHARED_RT.block_on(async {
2345            let client = MockAccountApiClient { force_error: false };
2346
2347            let params = RateLimitOrderParams::builder().build().unwrap();
2348
2349            let resp_json: Value = serde_json::from_str(r#"[{"rateLimitType":"ORDERS","interval":"SECOND","intervalNum":10,"limit":50,"count":0},{"rateLimitType":"ORDERS","interval":"DAY","intervalNum":1,"limit":160000,"count":0}]"#).unwrap();
2350            let expected_response : Vec<models::RateLimitOrderResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::RateLimitOrderResponseInner>");
2351
2352            let resp = client.rate_limit_order(params).await.expect("Expected a response");
2353            let data_future = resp.data();
2354            let actual_response = data_future.await.unwrap();
2355            assert_eq!(actual_response, expected_response);
2356        });
2357    }
2358
2359    #[test]
2360    fn rate_limit_order_optional_params_success() {
2361        TOKIO_SHARED_RT.block_on(async {
2362            let client = MockAccountApiClient { force_error: false };
2363
2364            let params = RateLimitOrderParams::builder().recv_window(dec!(5000.0)).build().unwrap();
2365
2366            let resp_json: Value = serde_json::from_str(r#"[{"rateLimitType":"ORDERS","interval":"SECOND","intervalNum":10,"limit":50,"count":0},{"rateLimitType":"ORDERS","interval":"DAY","intervalNum":1,"limit":160000,"count":0}]"#).unwrap();
2367            let expected_response : Vec<models::RateLimitOrderResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::RateLimitOrderResponseInner>");
2368
2369            let resp = client.rate_limit_order(params).await.expect("Expected a response");
2370            let data_future = resp.data();
2371            let actual_response = data_future.await.unwrap();
2372            assert_eq!(actual_response, expected_response);
2373        });
2374    }
2375
2376    #[test]
2377    fn rate_limit_order_response_error() {
2378        TOKIO_SHARED_RT.block_on(async {
2379            let client = MockAccountApiClient { force_error: true };
2380
2381            let params = RateLimitOrderParams::builder().build().unwrap();
2382
2383            match client.rate_limit_order(params).await {
2384                Ok(_) => panic!("Expected an error"),
2385                Err(err) => {
2386                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
2387                }
2388            }
2389        });
2390    }
2391}