Skip to main content

binance_sdk/spot/rest_api/apis/
market_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 MarketApi: Send + Sync {
39    async fn agg_trades(
40        &self,
41        params: AggTradesParams,
42    ) -> anyhow::Result<RestApiResponse<Vec<models::AggTradesResponseInner>>>;
43    async fn avg_price(
44        &self,
45        params: AvgPriceParams,
46    ) -> anyhow::Result<RestApiResponse<models::AvgPriceResponse>>;
47    async fn depth(
48        &self,
49        params: DepthParams,
50    ) -> anyhow::Result<RestApiResponse<models::DepthResponse>>;
51    async fn get_trades(
52        &self,
53        params: GetTradesParams,
54    ) -> anyhow::Result<RestApiResponse<Vec<models::HistoricalTradesResponseInner>>>;
55    async fn historical_block_trades(
56        &self,
57        params: HistoricalBlockTradesParams,
58    ) -> anyhow::Result<RestApiResponse<Vec<models::HistoricalBlockTradesResponseInner>>>;
59    async fn historical_trades(
60        &self,
61        params: HistoricalTradesParams,
62    ) -> anyhow::Result<RestApiResponse<Vec<models::HistoricalTradesResponseInner>>>;
63    async fn klines(
64        &self,
65        params: KlinesParams,
66    ) -> anyhow::Result<RestApiResponse<Vec<Vec<models::KlinesItemInner>>>>;
67    async fn reference_price(
68        &self,
69        params: ReferencePriceParams,
70    ) -> anyhow::Result<RestApiResponse<models::ReferencePriceResponse>>;
71    async fn reference_price_calculation(
72        &self,
73        params: ReferencePriceCalculationParams,
74    ) -> anyhow::Result<RestApiResponse<models::ReferencePriceCalculationResponse>>;
75    async fn ticker(
76        &self,
77        params: TickerParams,
78    ) -> anyhow::Result<RestApiResponse<models::TickerResponse>>;
79    async fn ticker24hr(
80        &self,
81        params: Ticker24hrParams,
82    ) -> anyhow::Result<RestApiResponse<models::Ticker24hrResponse>>;
83    async fn ticker_book_ticker(
84        &self,
85        params: TickerBookTickerParams,
86    ) -> anyhow::Result<RestApiResponse<models::TickerBookTickerResponse>>;
87    async fn ticker_price(
88        &self,
89        params: TickerPriceParams,
90    ) -> anyhow::Result<RestApiResponse<models::TickerPriceResponse>>;
91    async fn ticker_trading_day(
92        &self,
93        params: TickerTradingDayParams,
94    ) -> anyhow::Result<RestApiResponse<models::TickerTradingDayResponse>>;
95    async fn ui_klines(
96        &self,
97        params: UiKlinesParams,
98    ) -> anyhow::Result<RestApiResponse<Vec<Vec<models::KlinesItemInner>>>>;
99}
100
101#[derive(Debug, Clone)]
102pub struct MarketApiClient {
103    configuration: ConfigurationRestApi,
104}
105
106impl MarketApiClient {
107    pub fn new(configuration: ConfigurationRestApi) -> Self {
108        Self { configuration }
109    }
110}
111
112#[allow(non_camel_case_types)]
113#[derive(Debug, Clone, Serialize, Deserialize)]
114pub enum DepthSymbolStatusEnum {
115    #[serde(rename = "TRADING")]
116    Trading,
117    #[serde(rename = "END_OF_DAY")]
118    EndOfDay,
119    #[serde(rename = "HALT")]
120    Halt,
121    #[serde(rename = "BREAK")]
122    Break,
123    #[serde(rename = "NON_REPRESENTABLE")]
124    NonRepresentable,
125}
126
127impl DepthSymbolStatusEnum {
128    #[must_use]
129    pub fn as_str(&self) -> &'static str {
130        match self {
131            Self::Trading => "TRADING",
132            Self::EndOfDay => "END_OF_DAY",
133            Self::Halt => "HALT",
134            Self::Break => "BREAK",
135            Self::NonRepresentable => "NON_REPRESENTABLE",
136        }
137    }
138}
139
140impl std::str::FromStr for DepthSymbolStatusEnum {
141    type Err = Box<dyn std::error::Error + Send + Sync>;
142
143    fn from_str(s: &str) -> Result<Self, Self::Err> {
144        match s {
145            "TRADING" => Ok(Self::Trading),
146            "END_OF_DAY" => Ok(Self::EndOfDay),
147            "HALT" => Ok(Self::Halt),
148            "BREAK" => Ok(Self::Break),
149            "NON_REPRESENTABLE" => Ok(Self::NonRepresentable),
150            other => Err(format!("invalid DepthSymbolStatusEnum: {}", other).into()),
151        }
152    }
153}
154
155#[allow(non_camel_case_types)]
156#[derive(Debug, Clone, Serialize, Deserialize)]
157pub enum KlinesIntervalEnum {
158    #[serde(rename = "1s")]
159    Interval1s,
160    #[serde(rename = "1m")]
161    Interval1m,
162    #[serde(rename = "3m")]
163    Interval3m,
164    #[serde(rename = "5m")]
165    Interval5m,
166    #[serde(rename = "15m")]
167    Interval15m,
168    #[serde(rename = "30m")]
169    Interval30m,
170    #[serde(rename = "1h")]
171    Interval1h,
172    #[serde(rename = "2h")]
173    Interval2h,
174    #[serde(rename = "4h")]
175    Interval4h,
176    #[serde(rename = "6h")]
177    Interval6h,
178    #[serde(rename = "8h")]
179    Interval8h,
180    #[serde(rename = "12h")]
181    Interval12h,
182    #[serde(rename = "1d")]
183    Interval1d,
184    #[serde(rename = "3d")]
185    Interval3d,
186    #[serde(rename = "1w")]
187    Interval1w,
188    #[serde(rename = "1M")]
189    Interval1M,
190}
191
192impl KlinesIntervalEnum {
193    #[must_use]
194    pub fn as_str(&self) -> &'static str {
195        match self {
196            Self::Interval1s => "1s",
197            Self::Interval1m => "1m",
198            Self::Interval3m => "3m",
199            Self::Interval5m => "5m",
200            Self::Interval15m => "15m",
201            Self::Interval30m => "30m",
202            Self::Interval1h => "1h",
203            Self::Interval2h => "2h",
204            Self::Interval4h => "4h",
205            Self::Interval6h => "6h",
206            Self::Interval8h => "8h",
207            Self::Interval12h => "12h",
208            Self::Interval1d => "1d",
209            Self::Interval3d => "3d",
210            Self::Interval1w => "1w",
211            Self::Interval1M => "1M",
212        }
213    }
214}
215
216impl std::str::FromStr for KlinesIntervalEnum {
217    type Err = Box<dyn std::error::Error + Send + Sync>;
218
219    fn from_str(s: &str) -> Result<Self, Self::Err> {
220        match s {
221            "1s" => Ok(Self::Interval1s),
222            "1m" => Ok(Self::Interval1m),
223            "3m" => Ok(Self::Interval3m),
224            "5m" => Ok(Self::Interval5m),
225            "15m" => Ok(Self::Interval15m),
226            "30m" => Ok(Self::Interval30m),
227            "1h" => Ok(Self::Interval1h),
228            "2h" => Ok(Self::Interval2h),
229            "4h" => Ok(Self::Interval4h),
230            "6h" => Ok(Self::Interval6h),
231            "8h" => Ok(Self::Interval8h),
232            "12h" => Ok(Self::Interval12h),
233            "1d" => Ok(Self::Interval1d),
234            "3d" => Ok(Self::Interval3d),
235            "1w" => Ok(Self::Interval1w),
236            "1M" => Ok(Self::Interval1M),
237            other => Err(format!("invalid KlinesIntervalEnum: {}", other).into()),
238        }
239    }
240}
241
242#[allow(non_camel_case_types)]
243#[derive(Debug, Clone, Serialize, Deserialize)]
244pub enum ReferencePriceCalculationSymbolStatusEnum {
245    #[serde(rename = "TRADING")]
246    Trading,
247    #[serde(rename = "END_OF_DAY")]
248    EndOfDay,
249    #[serde(rename = "HALT")]
250    Halt,
251    #[serde(rename = "BREAK")]
252    Break,
253    #[serde(rename = "NON_REPRESENTABLE")]
254    NonRepresentable,
255}
256
257impl ReferencePriceCalculationSymbolStatusEnum {
258    #[must_use]
259    pub fn as_str(&self) -> &'static str {
260        match self {
261            Self::Trading => "TRADING",
262            Self::EndOfDay => "END_OF_DAY",
263            Self::Halt => "HALT",
264            Self::Break => "BREAK",
265            Self::NonRepresentable => "NON_REPRESENTABLE",
266        }
267    }
268}
269
270impl std::str::FromStr for ReferencePriceCalculationSymbolStatusEnum {
271    type Err = Box<dyn std::error::Error + Send + Sync>;
272
273    fn from_str(s: &str) -> Result<Self, Self::Err> {
274        match s {
275            "TRADING" => Ok(Self::Trading),
276            "END_OF_DAY" => Ok(Self::EndOfDay),
277            "HALT" => Ok(Self::Halt),
278            "BREAK" => Ok(Self::Break),
279            "NON_REPRESENTABLE" => Ok(Self::NonRepresentable),
280            other => Err(format!(
281                "invalid ReferencePriceCalculationSymbolStatusEnum: {}",
282                other
283            )
284            .into()),
285        }
286    }
287}
288
289#[allow(non_camel_case_types)]
290#[derive(Debug, Clone, Serialize, Deserialize)]
291pub enum TickerWindowSizeEnum {
292    #[serde(rename = "1m")]
293    WindowSize1m,
294    #[serde(rename = "2m")]
295    WindowSize2m,
296    #[serde(rename = "3m")]
297    WindowSize3m,
298    #[serde(rename = "4m")]
299    WindowSize4m,
300    #[serde(rename = "5m")]
301    WindowSize5m,
302    #[serde(rename = "6m")]
303    WindowSize6m,
304    #[serde(rename = "7m")]
305    WindowSize7m,
306    #[serde(rename = "8m")]
307    WindowSize8m,
308    #[serde(rename = "9m")]
309    WindowSize9m,
310    #[serde(rename = "10m")]
311    WindowSize10m,
312    #[serde(rename = "11m")]
313    WindowSize11m,
314    #[serde(rename = "12m")]
315    WindowSize12m,
316    #[serde(rename = "13m")]
317    WindowSize13m,
318    #[serde(rename = "14m")]
319    WindowSize14m,
320    #[serde(rename = "15m")]
321    WindowSize15m,
322    #[serde(rename = "16m")]
323    WindowSize16m,
324    #[serde(rename = "17m")]
325    WindowSize17m,
326    #[serde(rename = "18m")]
327    WindowSize18m,
328    #[serde(rename = "19m")]
329    WindowSize19m,
330    #[serde(rename = "20m")]
331    WindowSize20m,
332    #[serde(rename = "21m")]
333    WindowSize21m,
334    #[serde(rename = "22m")]
335    WindowSize22m,
336    #[serde(rename = "23m")]
337    WindowSize23m,
338    #[serde(rename = "24m")]
339    WindowSize24m,
340    #[serde(rename = "25m")]
341    WindowSize25m,
342    #[serde(rename = "26m")]
343    WindowSize26m,
344    #[serde(rename = "27m")]
345    WindowSize27m,
346    #[serde(rename = "28m")]
347    WindowSize28m,
348    #[serde(rename = "29m")]
349    WindowSize29m,
350    #[serde(rename = "30m")]
351    WindowSize30m,
352    #[serde(rename = "31m")]
353    WindowSize31m,
354    #[serde(rename = "32m")]
355    WindowSize32m,
356    #[serde(rename = "33m")]
357    WindowSize33m,
358    #[serde(rename = "34m")]
359    WindowSize34m,
360    #[serde(rename = "35m")]
361    WindowSize35m,
362    #[serde(rename = "36m")]
363    WindowSize36m,
364    #[serde(rename = "37m")]
365    WindowSize37m,
366    #[serde(rename = "38m")]
367    WindowSize38m,
368    #[serde(rename = "39m")]
369    WindowSize39m,
370    #[serde(rename = "40m")]
371    WindowSize40m,
372    #[serde(rename = "41m")]
373    WindowSize41m,
374    #[serde(rename = "42m")]
375    WindowSize42m,
376    #[serde(rename = "43m")]
377    WindowSize43m,
378    #[serde(rename = "44m")]
379    WindowSize44m,
380    #[serde(rename = "45m")]
381    WindowSize45m,
382    #[serde(rename = "46m")]
383    WindowSize46m,
384    #[serde(rename = "47m")]
385    WindowSize47m,
386    #[serde(rename = "48m")]
387    WindowSize48m,
388    #[serde(rename = "49m")]
389    WindowSize49m,
390    #[serde(rename = "50m")]
391    WindowSize50m,
392    #[serde(rename = "51m")]
393    WindowSize51m,
394    #[serde(rename = "52m")]
395    WindowSize52m,
396    #[serde(rename = "53m")]
397    WindowSize53m,
398    #[serde(rename = "54m")]
399    WindowSize54m,
400    #[serde(rename = "55m")]
401    WindowSize55m,
402    #[serde(rename = "56m")]
403    WindowSize56m,
404    #[serde(rename = "57m")]
405    WindowSize57m,
406    #[serde(rename = "58m")]
407    WindowSize58m,
408    #[serde(rename = "59m")]
409    WindowSize59m,
410    #[serde(rename = "1h")]
411    WindowSize1h,
412    #[serde(rename = "2h")]
413    WindowSize2h,
414    #[serde(rename = "3h")]
415    WindowSize3h,
416    #[serde(rename = "4h")]
417    WindowSize4h,
418    #[serde(rename = "5h")]
419    WindowSize5h,
420    #[serde(rename = "6h")]
421    WindowSize6h,
422    #[serde(rename = "7h")]
423    WindowSize7h,
424    #[serde(rename = "8h")]
425    WindowSize8h,
426    #[serde(rename = "9h")]
427    WindowSize9h,
428    #[serde(rename = "10h")]
429    WindowSize10h,
430    #[serde(rename = "11h")]
431    WindowSize11h,
432    #[serde(rename = "12h")]
433    WindowSize12h,
434    #[serde(rename = "13h")]
435    WindowSize13h,
436    #[serde(rename = "14h")]
437    WindowSize14h,
438    #[serde(rename = "15h")]
439    WindowSize15h,
440    #[serde(rename = "16h")]
441    WindowSize16h,
442    #[serde(rename = "17h")]
443    WindowSize17h,
444    #[serde(rename = "18h")]
445    WindowSize18h,
446    #[serde(rename = "19h")]
447    WindowSize19h,
448    #[serde(rename = "20h")]
449    WindowSize20h,
450    #[serde(rename = "21h")]
451    WindowSize21h,
452    #[serde(rename = "22h")]
453    WindowSize22h,
454    #[serde(rename = "23h")]
455    WindowSize23h,
456    #[serde(rename = "1d")]
457    WindowSize1d,
458    #[serde(rename = "2d")]
459    WindowSize2d,
460    #[serde(rename = "3d")]
461    WindowSize3d,
462    #[serde(rename = "4d")]
463    WindowSize4d,
464    #[serde(rename = "5d")]
465    WindowSize5d,
466    #[serde(rename = "6d")]
467    WindowSize6d,
468}
469
470impl TickerWindowSizeEnum {
471    #[must_use]
472    pub fn as_str(&self) -> &'static str {
473        match self {
474            Self::WindowSize1m => "1m",
475            Self::WindowSize2m => "2m",
476            Self::WindowSize3m => "3m",
477            Self::WindowSize4m => "4m",
478            Self::WindowSize5m => "5m",
479            Self::WindowSize6m => "6m",
480            Self::WindowSize7m => "7m",
481            Self::WindowSize8m => "8m",
482            Self::WindowSize9m => "9m",
483            Self::WindowSize10m => "10m",
484            Self::WindowSize11m => "11m",
485            Self::WindowSize12m => "12m",
486            Self::WindowSize13m => "13m",
487            Self::WindowSize14m => "14m",
488            Self::WindowSize15m => "15m",
489            Self::WindowSize16m => "16m",
490            Self::WindowSize17m => "17m",
491            Self::WindowSize18m => "18m",
492            Self::WindowSize19m => "19m",
493            Self::WindowSize20m => "20m",
494            Self::WindowSize21m => "21m",
495            Self::WindowSize22m => "22m",
496            Self::WindowSize23m => "23m",
497            Self::WindowSize24m => "24m",
498            Self::WindowSize25m => "25m",
499            Self::WindowSize26m => "26m",
500            Self::WindowSize27m => "27m",
501            Self::WindowSize28m => "28m",
502            Self::WindowSize29m => "29m",
503            Self::WindowSize30m => "30m",
504            Self::WindowSize31m => "31m",
505            Self::WindowSize32m => "32m",
506            Self::WindowSize33m => "33m",
507            Self::WindowSize34m => "34m",
508            Self::WindowSize35m => "35m",
509            Self::WindowSize36m => "36m",
510            Self::WindowSize37m => "37m",
511            Self::WindowSize38m => "38m",
512            Self::WindowSize39m => "39m",
513            Self::WindowSize40m => "40m",
514            Self::WindowSize41m => "41m",
515            Self::WindowSize42m => "42m",
516            Self::WindowSize43m => "43m",
517            Self::WindowSize44m => "44m",
518            Self::WindowSize45m => "45m",
519            Self::WindowSize46m => "46m",
520            Self::WindowSize47m => "47m",
521            Self::WindowSize48m => "48m",
522            Self::WindowSize49m => "49m",
523            Self::WindowSize50m => "50m",
524            Self::WindowSize51m => "51m",
525            Self::WindowSize52m => "52m",
526            Self::WindowSize53m => "53m",
527            Self::WindowSize54m => "54m",
528            Self::WindowSize55m => "55m",
529            Self::WindowSize56m => "56m",
530            Self::WindowSize57m => "57m",
531            Self::WindowSize58m => "58m",
532            Self::WindowSize59m => "59m",
533            Self::WindowSize1h => "1h",
534            Self::WindowSize2h => "2h",
535            Self::WindowSize3h => "3h",
536            Self::WindowSize4h => "4h",
537            Self::WindowSize5h => "5h",
538            Self::WindowSize6h => "6h",
539            Self::WindowSize7h => "7h",
540            Self::WindowSize8h => "8h",
541            Self::WindowSize9h => "9h",
542            Self::WindowSize10h => "10h",
543            Self::WindowSize11h => "11h",
544            Self::WindowSize12h => "12h",
545            Self::WindowSize13h => "13h",
546            Self::WindowSize14h => "14h",
547            Self::WindowSize15h => "15h",
548            Self::WindowSize16h => "16h",
549            Self::WindowSize17h => "17h",
550            Self::WindowSize18h => "18h",
551            Self::WindowSize19h => "19h",
552            Self::WindowSize20h => "20h",
553            Self::WindowSize21h => "21h",
554            Self::WindowSize22h => "22h",
555            Self::WindowSize23h => "23h",
556            Self::WindowSize1d => "1d",
557            Self::WindowSize2d => "2d",
558            Self::WindowSize3d => "3d",
559            Self::WindowSize4d => "4d",
560            Self::WindowSize5d => "5d",
561            Self::WindowSize6d => "6d",
562        }
563    }
564}
565
566impl std::str::FromStr for TickerWindowSizeEnum {
567    type Err = Box<dyn std::error::Error + Send + Sync>;
568
569    fn from_str(s: &str) -> Result<Self, Self::Err> {
570        match s {
571            "1m" => Ok(Self::WindowSize1m),
572            "2m" => Ok(Self::WindowSize2m),
573            "3m" => Ok(Self::WindowSize3m),
574            "4m" => Ok(Self::WindowSize4m),
575            "5m" => Ok(Self::WindowSize5m),
576            "6m" => Ok(Self::WindowSize6m),
577            "7m" => Ok(Self::WindowSize7m),
578            "8m" => Ok(Self::WindowSize8m),
579            "9m" => Ok(Self::WindowSize9m),
580            "10m" => Ok(Self::WindowSize10m),
581            "11m" => Ok(Self::WindowSize11m),
582            "12m" => Ok(Self::WindowSize12m),
583            "13m" => Ok(Self::WindowSize13m),
584            "14m" => Ok(Self::WindowSize14m),
585            "15m" => Ok(Self::WindowSize15m),
586            "16m" => Ok(Self::WindowSize16m),
587            "17m" => Ok(Self::WindowSize17m),
588            "18m" => Ok(Self::WindowSize18m),
589            "19m" => Ok(Self::WindowSize19m),
590            "20m" => Ok(Self::WindowSize20m),
591            "21m" => Ok(Self::WindowSize21m),
592            "22m" => Ok(Self::WindowSize22m),
593            "23m" => Ok(Self::WindowSize23m),
594            "24m" => Ok(Self::WindowSize24m),
595            "25m" => Ok(Self::WindowSize25m),
596            "26m" => Ok(Self::WindowSize26m),
597            "27m" => Ok(Self::WindowSize27m),
598            "28m" => Ok(Self::WindowSize28m),
599            "29m" => Ok(Self::WindowSize29m),
600            "30m" => Ok(Self::WindowSize30m),
601            "31m" => Ok(Self::WindowSize31m),
602            "32m" => Ok(Self::WindowSize32m),
603            "33m" => Ok(Self::WindowSize33m),
604            "34m" => Ok(Self::WindowSize34m),
605            "35m" => Ok(Self::WindowSize35m),
606            "36m" => Ok(Self::WindowSize36m),
607            "37m" => Ok(Self::WindowSize37m),
608            "38m" => Ok(Self::WindowSize38m),
609            "39m" => Ok(Self::WindowSize39m),
610            "40m" => Ok(Self::WindowSize40m),
611            "41m" => Ok(Self::WindowSize41m),
612            "42m" => Ok(Self::WindowSize42m),
613            "43m" => Ok(Self::WindowSize43m),
614            "44m" => Ok(Self::WindowSize44m),
615            "45m" => Ok(Self::WindowSize45m),
616            "46m" => Ok(Self::WindowSize46m),
617            "47m" => Ok(Self::WindowSize47m),
618            "48m" => Ok(Self::WindowSize48m),
619            "49m" => Ok(Self::WindowSize49m),
620            "50m" => Ok(Self::WindowSize50m),
621            "51m" => Ok(Self::WindowSize51m),
622            "52m" => Ok(Self::WindowSize52m),
623            "53m" => Ok(Self::WindowSize53m),
624            "54m" => Ok(Self::WindowSize54m),
625            "55m" => Ok(Self::WindowSize55m),
626            "56m" => Ok(Self::WindowSize56m),
627            "57m" => Ok(Self::WindowSize57m),
628            "58m" => Ok(Self::WindowSize58m),
629            "59m" => Ok(Self::WindowSize59m),
630            "1h" => Ok(Self::WindowSize1h),
631            "2h" => Ok(Self::WindowSize2h),
632            "3h" => Ok(Self::WindowSize3h),
633            "4h" => Ok(Self::WindowSize4h),
634            "5h" => Ok(Self::WindowSize5h),
635            "6h" => Ok(Self::WindowSize6h),
636            "7h" => Ok(Self::WindowSize7h),
637            "8h" => Ok(Self::WindowSize8h),
638            "9h" => Ok(Self::WindowSize9h),
639            "10h" => Ok(Self::WindowSize10h),
640            "11h" => Ok(Self::WindowSize11h),
641            "12h" => Ok(Self::WindowSize12h),
642            "13h" => Ok(Self::WindowSize13h),
643            "14h" => Ok(Self::WindowSize14h),
644            "15h" => Ok(Self::WindowSize15h),
645            "16h" => Ok(Self::WindowSize16h),
646            "17h" => Ok(Self::WindowSize17h),
647            "18h" => Ok(Self::WindowSize18h),
648            "19h" => Ok(Self::WindowSize19h),
649            "20h" => Ok(Self::WindowSize20h),
650            "21h" => Ok(Self::WindowSize21h),
651            "22h" => Ok(Self::WindowSize22h),
652            "23h" => Ok(Self::WindowSize23h),
653            "1d" => Ok(Self::WindowSize1d),
654            "2d" => Ok(Self::WindowSize2d),
655            "3d" => Ok(Self::WindowSize3d),
656            "4d" => Ok(Self::WindowSize4d),
657            "5d" => Ok(Self::WindowSize5d),
658            "6d" => Ok(Self::WindowSize6d),
659            other => Err(format!("invalid TickerWindowSizeEnum: {}", other).into()),
660        }
661    }
662}
663
664#[allow(non_camel_case_types)]
665#[derive(Debug, Clone, Serialize, Deserialize)]
666pub enum TickerTypeEnum {
667    #[serde(rename = "FULL")]
668    Full,
669    #[serde(rename = "MINI")]
670    Mini,
671}
672
673impl TickerTypeEnum {
674    #[must_use]
675    pub fn as_str(&self) -> &'static str {
676        match self {
677            Self::Full => "FULL",
678            Self::Mini => "MINI",
679        }
680    }
681}
682
683impl std::str::FromStr for TickerTypeEnum {
684    type Err = Box<dyn std::error::Error + Send + Sync>;
685
686    fn from_str(s: &str) -> Result<Self, Self::Err> {
687        match s {
688            "FULL" => Ok(Self::Full),
689            "MINI" => Ok(Self::Mini),
690            other => Err(format!("invalid TickerTypeEnum: {}", other).into()),
691        }
692    }
693}
694
695#[allow(non_camel_case_types)]
696#[derive(Debug, Clone, Serialize, Deserialize)]
697pub enum TickerSymbolStatusEnum {
698    #[serde(rename = "TRADING")]
699    Trading,
700    #[serde(rename = "END_OF_DAY")]
701    EndOfDay,
702    #[serde(rename = "HALT")]
703    Halt,
704    #[serde(rename = "BREAK")]
705    Break,
706    #[serde(rename = "NON_REPRESENTABLE")]
707    NonRepresentable,
708}
709
710impl TickerSymbolStatusEnum {
711    #[must_use]
712    pub fn as_str(&self) -> &'static str {
713        match self {
714            Self::Trading => "TRADING",
715            Self::EndOfDay => "END_OF_DAY",
716            Self::Halt => "HALT",
717            Self::Break => "BREAK",
718            Self::NonRepresentable => "NON_REPRESENTABLE",
719        }
720    }
721}
722
723impl std::str::FromStr for TickerSymbolStatusEnum {
724    type Err = Box<dyn std::error::Error + Send + Sync>;
725
726    fn from_str(s: &str) -> Result<Self, Self::Err> {
727        match s {
728            "TRADING" => Ok(Self::Trading),
729            "END_OF_DAY" => Ok(Self::EndOfDay),
730            "HALT" => Ok(Self::Halt),
731            "BREAK" => Ok(Self::Break),
732            "NON_REPRESENTABLE" => Ok(Self::NonRepresentable),
733            other => Err(format!("invalid TickerSymbolStatusEnum: {}", other).into()),
734        }
735    }
736}
737
738#[allow(non_camel_case_types)]
739#[derive(Debug, Clone, Serialize, Deserialize)]
740pub enum Ticker24hrTypeEnum {
741    #[serde(rename = "FULL")]
742    Full,
743    #[serde(rename = "MINI")]
744    Mini,
745}
746
747impl Ticker24hrTypeEnum {
748    #[must_use]
749    pub fn as_str(&self) -> &'static str {
750        match self {
751            Self::Full => "FULL",
752            Self::Mini => "MINI",
753        }
754    }
755}
756
757impl std::str::FromStr for Ticker24hrTypeEnum {
758    type Err = Box<dyn std::error::Error + Send + Sync>;
759
760    fn from_str(s: &str) -> Result<Self, Self::Err> {
761        match s {
762            "FULL" => Ok(Self::Full),
763            "MINI" => Ok(Self::Mini),
764            other => Err(format!("invalid Ticker24hrTypeEnum: {}", other).into()),
765        }
766    }
767}
768
769#[allow(non_camel_case_types)]
770#[derive(Debug, Clone, Serialize, Deserialize)]
771pub enum Ticker24hrSymbolStatusEnum {
772    #[serde(rename = "TRADING")]
773    Trading,
774    #[serde(rename = "END_OF_DAY")]
775    EndOfDay,
776    #[serde(rename = "HALT")]
777    Halt,
778    #[serde(rename = "BREAK")]
779    Break,
780    #[serde(rename = "NON_REPRESENTABLE")]
781    NonRepresentable,
782}
783
784impl Ticker24hrSymbolStatusEnum {
785    #[must_use]
786    pub fn as_str(&self) -> &'static str {
787        match self {
788            Self::Trading => "TRADING",
789            Self::EndOfDay => "END_OF_DAY",
790            Self::Halt => "HALT",
791            Self::Break => "BREAK",
792            Self::NonRepresentable => "NON_REPRESENTABLE",
793        }
794    }
795}
796
797impl std::str::FromStr for Ticker24hrSymbolStatusEnum {
798    type Err = Box<dyn std::error::Error + Send + Sync>;
799
800    fn from_str(s: &str) -> Result<Self, Self::Err> {
801        match s {
802            "TRADING" => Ok(Self::Trading),
803            "END_OF_DAY" => Ok(Self::EndOfDay),
804            "HALT" => Ok(Self::Halt),
805            "BREAK" => Ok(Self::Break),
806            "NON_REPRESENTABLE" => Ok(Self::NonRepresentable),
807            other => Err(format!("invalid Ticker24hrSymbolStatusEnum: {}", other).into()),
808        }
809    }
810}
811
812#[allow(non_camel_case_types)]
813#[derive(Debug, Clone, Serialize, Deserialize)]
814pub enum TickerBookTickerSymbolStatusEnum {
815    #[serde(rename = "TRADING")]
816    Trading,
817    #[serde(rename = "END_OF_DAY")]
818    EndOfDay,
819    #[serde(rename = "HALT")]
820    Halt,
821    #[serde(rename = "BREAK")]
822    Break,
823    #[serde(rename = "NON_REPRESENTABLE")]
824    NonRepresentable,
825}
826
827impl TickerBookTickerSymbolStatusEnum {
828    #[must_use]
829    pub fn as_str(&self) -> &'static str {
830        match self {
831            Self::Trading => "TRADING",
832            Self::EndOfDay => "END_OF_DAY",
833            Self::Halt => "HALT",
834            Self::Break => "BREAK",
835            Self::NonRepresentable => "NON_REPRESENTABLE",
836        }
837    }
838}
839
840impl std::str::FromStr for TickerBookTickerSymbolStatusEnum {
841    type Err = Box<dyn std::error::Error + Send + Sync>;
842
843    fn from_str(s: &str) -> Result<Self, Self::Err> {
844        match s {
845            "TRADING" => Ok(Self::Trading),
846            "END_OF_DAY" => Ok(Self::EndOfDay),
847            "HALT" => Ok(Self::Halt),
848            "BREAK" => Ok(Self::Break),
849            "NON_REPRESENTABLE" => Ok(Self::NonRepresentable),
850            other => Err(format!("invalid TickerBookTickerSymbolStatusEnum: {}", other).into()),
851        }
852    }
853}
854
855#[allow(non_camel_case_types)]
856#[derive(Debug, Clone, Serialize, Deserialize)]
857pub enum TickerPriceSymbolStatusEnum {
858    #[serde(rename = "TRADING")]
859    Trading,
860    #[serde(rename = "END_OF_DAY")]
861    EndOfDay,
862    #[serde(rename = "HALT")]
863    Halt,
864    #[serde(rename = "BREAK")]
865    Break,
866    #[serde(rename = "NON_REPRESENTABLE")]
867    NonRepresentable,
868}
869
870impl TickerPriceSymbolStatusEnum {
871    #[must_use]
872    pub fn as_str(&self) -> &'static str {
873        match self {
874            Self::Trading => "TRADING",
875            Self::EndOfDay => "END_OF_DAY",
876            Self::Halt => "HALT",
877            Self::Break => "BREAK",
878            Self::NonRepresentable => "NON_REPRESENTABLE",
879        }
880    }
881}
882
883impl std::str::FromStr for TickerPriceSymbolStatusEnum {
884    type Err = Box<dyn std::error::Error + Send + Sync>;
885
886    fn from_str(s: &str) -> Result<Self, Self::Err> {
887        match s {
888            "TRADING" => Ok(Self::Trading),
889            "END_OF_DAY" => Ok(Self::EndOfDay),
890            "HALT" => Ok(Self::Halt),
891            "BREAK" => Ok(Self::Break),
892            "NON_REPRESENTABLE" => Ok(Self::NonRepresentable),
893            other => Err(format!("invalid TickerPriceSymbolStatusEnum: {}", other).into()),
894        }
895    }
896}
897
898#[allow(non_camel_case_types)]
899#[derive(Debug, Clone, Serialize, Deserialize)]
900pub enum TickerTradingDayTypeEnum {
901    #[serde(rename = "FULL")]
902    Full,
903    #[serde(rename = "MINI")]
904    Mini,
905}
906
907impl TickerTradingDayTypeEnum {
908    #[must_use]
909    pub fn as_str(&self) -> &'static str {
910        match self {
911            Self::Full => "FULL",
912            Self::Mini => "MINI",
913        }
914    }
915}
916
917impl std::str::FromStr for TickerTradingDayTypeEnum {
918    type Err = Box<dyn std::error::Error + Send + Sync>;
919
920    fn from_str(s: &str) -> Result<Self, Self::Err> {
921        match s {
922            "FULL" => Ok(Self::Full),
923            "MINI" => Ok(Self::Mini),
924            other => Err(format!("invalid TickerTradingDayTypeEnum: {}", other).into()),
925        }
926    }
927}
928
929#[allow(non_camel_case_types)]
930#[derive(Debug, Clone, Serialize, Deserialize)]
931pub enum TickerTradingDaySymbolStatusEnum {
932    #[serde(rename = "TRADING")]
933    Trading,
934    #[serde(rename = "END_OF_DAY")]
935    EndOfDay,
936    #[serde(rename = "HALT")]
937    Halt,
938    #[serde(rename = "BREAK")]
939    Break,
940    #[serde(rename = "NON_REPRESENTABLE")]
941    NonRepresentable,
942}
943
944impl TickerTradingDaySymbolStatusEnum {
945    #[must_use]
946    pub fn as_str(&self) -> &'static str {
947        match self {
948            Self::Trading => "TRADING",
949            Self::EndOfDay => "END_OF_DAY",
950            Self::Halt => "HALT",
951            Self::Break => "BREAK",
952            Self::NonRepresentable => "NON_REPRESENTABLE",
953        }
954    }
955}
956
957impl std::str::FromStr for TickerTradingDaySymbolStatusEnum {
958    type Err = Box<dyn std::error::Error + Send + Sync>;
959
960    fn from_str(s: &str) -> Result<Self, Self::Err> {
961        match s {
962            "TRADING" => Ok(Self::Trading),
963            "END_OF_DAY" => Ok(Self::EndOfDay),
964            "HALT" => Ok(Self::Halt),
965            "BREAK" => Ok(Self::Break),
966            "NON_REPRESENTABLE" => Ok(Self::NonRepresentable),
967            other => Err(format!("invalid TickerTradingDaySymbolStatusEnum: {}", other).into()),
968        }
969    }
970}
971
972#[allow(non_camel_case_types)]
973#[derive(Debug, Clone, Serialize, Deserialize)]
974pub enum UiKlinesIntervalEnum {
975    #[serde(rename = "1s")]
976    Interval1s,
977    #[serde(rename = "1m")]
978    Interval1m,
979    #[serde(rename = "3m")]
980    Interval3m,
981    #[serde(rename = "5m")]
982    Interval5m,
983    #[serde(rename = "15m")]
984    Interval15m,
985    #[serde(rename = "30m")]
986    Interval30m,
987    #[serde(rename = "1h")]
988    Interval1h,
989    #[serde(rename = "2h")]
990    Interval2h,
991    #[serde(rename = "4h")]
992    Interval4h,
993    #[serde(rename = "6h")]
994    Interval6h,
995    #[serde(rename = "8h")]
996    Interval8h,
997    #[serde(rename = "12h")]
998    Interval12h,
999    #[serde(rename = "1d")]
1000    Interval1d,
1001    #[serde(rename = "3d")]
1002    Interval3d,
1003    #[serde(rename = "1w")]
1004    Interval1w,
1005    #[serde(rename = "1M")]
1006    Interval1M,
1007}
1008
1009impl UiKlinesIntervalEnum {
1010    #[must_use]
1011    pub fn as_str(&self) -> &'static str {
1012        match self {
1013            Self::Interval1s => "1s",
1014            Self::Interval1m => "1m",
1015            Self::Interval3m => "3m",
1016            Self::Interval5m => "5m",
1017            Self::Interval15m => "15m",
1018            Self::Interval30m => "30m",
1019            Self::Interval1h => "1h",
1020            Self::Interval2h => "2h",
1021            Self::Interval4h => "4h",
1022            Self::Interval6h => "6h",
1023            Self::Interval8h => "8h",
1024            Self::Interval12h => "12h",
1025            Self::Interval1d => "1d",
1026            Self::Interval3d => "3d",
1027            Self::Interval1w => "1w",
1028            Self::Interval1M => "1M",
1029        }
1030    }
1031}
1032
1033impl std::str::FromStr for UiKlinesIntervalEnum {
1034    type Err = Box<dyn std::error::Error + Send + Sync>;
1035
1036    fn from_str(s: &str) -> Result<Self, Self::Err> {
1037        match s {
1038            "1s" => Ok(Self::Interval1s),
1039            "1m" => Ok(Self::Interval1m),
1040            "3m" => Ok(Self::Interval3m),
1041            "5m" => Ok(Self::Interval5m),
1042            "15m" => Ok(Self::Interval15m),
1043            "30m" => Ok(Self::Interval30m),
1044            "1h" => Ok(Self::Interval1h),
1045            "2h" => Ok(Self::Interval2h),
1046            "4h" => Ok(Self::Interval4h),
1047            "6h" => Ok(Self::Interval6h),
1048            "8h" => Ok(Self::Interval8h),
1049            "12h" => Ok(Self::Interval12h),
1050            "1d" => Ok(Self::Interval1d),
1051            "3d" => Ok(Self::Interval3d),
1052            "1w" => Ok(Self::Interval1w),
1053            "1M" => Ok(Self::Interval1M),
1054            other => Err(format!("invalid UiKlinesIntervalEnum: {}", other).into()),
1055        }
1056    }
1057}
1058
1059/// Request parameters for the [`agg_trades`] operation.
1060///
1061/// This struct holds all of the inputs you can pass when calling
1062/// [`agg_trades`](#method.agg_trades).
1063#[derive(Clone, Debug, Builder)]
1064#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1065pub struct AggTradesParams {
1066    ///
1067    /// The `symbol` parameter.
1068    ///
1069    /// This field is **required.
1070    #[builder(setter(into))]
1071    pub symbol: String,
1072    /// ID to get aggregate trades from INCLUSIVE.
1073    ///
1074    /// This field is **optional.
1075    #[builder(setter(into), default)]
1076    pub from_id: Option<i64>,
1077    /// Timestamp in ms to get aggregate trades from INCLUSIVE.
1078    ///
1079    /// This field is **optional.
1080    #[builder(setter(into), default)]
1081    pub start_time: Option<i64>,
1082    /// Timestamp in ms to get aggregate trades until INCLUSIVE.
1083    ///
1084    /// This field is **optional.
1085    #[builder(setter(into), default)]
1086    pub end_time: Option<i64>,
1087    /// Default: 500; Maximum: 1000.
1088    ///
1089    /// This field is **optional.
1090    #[builder(setter(into), default)]
1091    pub limit: Option<i32>,
1092}
1093
1094impl AggTradesParams {
1095    /// Create a builder for [`agg_trades`].
1096    ///
1097    /// Required parameters:
1098    ///
1099    /// * `symbol` — String
1100    ///
1101    #[must_use]
1102    pub fn builder(symbol: String) -> AggTradesParamsBuilder {
1103        AggTradesParamsBuilder::default().symbol(symbol)
1104    }
1105}
1106/// Request parameters for the [`avg_price`] operation.
1107///
1108/// This struct holds all of the inputs you can pass when calling
1109/// [`avg_price`](#method.avg_price).
1110#[derive(Clone, Debug, Builder)]
1111#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1112pub struct AvgPriceParams {
1113    ///
1114    /// The `symbol` parameter.
1115    ///
1116    /// This field is **required.
1117    #[builder(setter(into))]
1118    pub symbol: String,
1119}
1120
1121impl AvgPriceParams {
1122    /// Create a builder for [`avg_price`].
1123    ///
1124    /// Required parameters:
1125    ///
1126    /// * `symbol` — String
1127    ///
1128    #[must_use]
1129    pub fn builder(symbol: String) -> AvgPriceParamsBuilder {
1130        AvgPriceParamsBuilder::default().symbol(symbol)
1131    }
1132}
1133/// Request parameters for the [`depth`] operation.
1134///
1135/// This struct holds all of the inputs you can pass when calling
1136/// [`depth`](#method.depth).
1137#[derive(Clone, Debug, Builder)]
1138#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1139pub struct DepthParams {
1140    ///
1141    /// The `symbol` parameter.
1142    ///
1143    /// This field is **required.
1144    #[builder(setter(into))]
1145    pub symbol: String,
1146    /// Default: 500; Maximum: 1000.
1147    ///
1148    /// This field is **optional.
1149    #[builder(setter(into), default)]
1150    pub limit: Option<i32>,
1151    ///
1152    /// The `symbol_status` parameter.
1153    ///
1154    /// This field is **optional.
1155    #[builder(setter(into), default)]
1156    pub symbol_status: Option<DepthSymbolStatusEnum>,
1157}
1158
1159impl DepthParams {
1160    /// Create a builder for [`depth`].
1161    ///
1162    /// Required parameters:
1163    ///
1164    /// * `symbol` — String
1165    ///
1166    #[must_use]
1167    pub fn builder(symbol: String) -> DepthParamsBuilder {
1168        DepthParamsBuilder::default().symbol(symbol)
1169    }
1170}
1171/// Request parameters for the [`get_trades`] operation.
1172///
1173/// This struct holds all of the inputs you can pass when calling
1174/// [`get_trades`](#method.get_trades).
1175#[derive(Clone, Debug, Builder)]
1176#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1177pub struct GetTradesParams {
1178    ///
1179    /// The `symbol` parameter.
1180    ///
1181    /// This field is **required.
1182    #[builder(setter(into))]
1183    pub symbol: String,
1184    /// Default: 500; Maximum: 1000.
1185    ///
1186    /// This field is **optional.
1187    #[builder(setter(into), default)]
1188    pub limit: Option<i32>,
1189}
1190
1191impl GetTradesParams {
1192    /// Create a builder for [`get_trades`].
1193    ///
1194    /// Required parameters:
1195    ///
1196    /// * `symbol` — String
1197    ///
1198    #[must_use]
1199    pub fn builder(symbol: String) -> GetTradesParamsBuilder {
1200        GetTradesParamsBuilder::default().symbol(symbol)
1201    }
1202}
1203/// Request parameters for the [`historical_block_trades`] operation.
1204///
1205/// This struct holds all of the inputs you can pass when calling
1206/// [`historical_block_trades`](#method.historical_block_trades).
1207#[derive(Clone, Debug, Builder)]
1208#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1209pub struct HistoricalBlockTradesParams {
1210    ///
1211    /// The `symbol` parameter.
1212    ///
1213    /// This field is **required.
1214    #[builder(setter(into))]
1215    pub symbol: String,
1216    /// Block trade ID to fetch from
1217    ///
1218    /// This field is **required.
1219    #[builder(setter(into))]
1220    pub from_id: i64,
1221    /// Default: 500; Maximum: 1000
1222    ///
1223    /// This field is **optional.
1224    #[builder(setter(into), default)]
1225    pub limit: Option<i64>,
1226}
1227
1228impl HistoricalBlockTradesParams {
1229    /// Create a builder for [`historical_block_trades`].
1230    ///
1231    /// Required parameters:
1232    ///
1233    /// * `symbol` — String
1234    /// * `from_id` — Block trade ID to fetch from
1235    ///
1236    #[must_use]
1237    pub fn builder(symbol: String, from_id: i64) -> HistoricalBlockTradesParamsBuilder {
1238        HistoricalBlockTradesParamsBuilder::default()
1239            .symbol(symbol)
1240            .from_id(from_id)
1241    }
1242}
1243/// Request parameters for the [`historical_trades`] operation.
1244///
1245/// This struct holds all of the inputs you can pass when calling
1246/// [`historical_trades`](#method.historical_trades).
1247#[derive(Clone, Debug, Builder)]
1248#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1249pub struct HistoricalTradesParams {
1250    ///
1251    /// The `symbol` parameter.
1252    ///
1253    /// This field is **required.
1254    #[builder(setter(into))]
1255    pub symbol: String,
1256    /// Default: 500; Maximum: 1000.
1257    ///
1258    /// This field is **optional.
1259    #[builder(setter(into), default)]
1260    pub limit: Option<i32>,
1261    /// ID to get aggregate trades from INCLUSIVE.
1262    ///
1263    /// This field is **optional.
1264    #[builder(setter(into), default)]
1265    pub from_id: Option<i64>,
1266}
1267
1268impl HistoricalTradesParams {
1269    /// Create a builder for [`historical_trades`].
1270    ///
1271    /// Required parameters:
1272    ///
1273    /// * `symbol` — String
1274    ///
1275    #[must_use]
1276    pub fn builder(symbol: String) -> HistoricalTradesParamsBuilder {
1277        HistoricalTradesParamsBuilder::default().symbol(symbol)
1278    }
1279}
1280/// Request parameters for the [`klines`] operation.
1281///
1282/// This struct holds all of the inputs you can pass when calling
1283/// [`klines`](#method.klines).
1284#[derive(Clone, Debug, Builder)]
1285#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1286pub struct KlinesParams {
1287    ///
1288    /// The `symbol` parameter.
1289    ///
1290    /// This field is **required.
1291    #[builder(setter(into))]
1292    pub symbol: String,
1293    ///
1294    /// The `interval` parameter.
1295    ///
1296    /// This field is **required.
1297    #[builder(setter(into))]
1298    pub interval: KlinesIntervalEnum,
1299    /// Timestamp in ms to get aggregate trades from INCLUSIVE.
1300    ///
1301    /// This field is **optional.
1302    #[builder(setter(into), default)]
1303    pub start_time: Option<i64>,
1304    /// Timestamp in ms to get aggregate trades until INCLUSIVE.
1305    ///
1306    /// This field is **optional.
1307    #[builder(setter(into), default)]
1308    pub end_time: Option<i64>,
1309    /// Default: 0 (UTC)
1310    ///
1311    /// This field is **optional.
1312    #[builder(setter(into), default)]
1313    pub time_zone: Option<String>,
1314    /// Default: 500; Maximum: 1000.
1315    ///
1316    /// This field is **optional.
1317    #[builder(setter(into), default)]
1318    pub limit: Option<i32>,
1319}
1320
1321impl KlinesParams {
1322    /// Create a builder for [`klines`].
1323    ///
1324    /// Required parameters:
1325    ///
1326    /// * `symbol` — String
1327    /// * `interval` — String
1328    ///
1329    #[must_use]
1330    pub fn builder(symbol: String, interval: KlinesIntervalEnum) -> KlinesParamsBuilder {
1331        KlinesParamsBuilder::default()
1332            .symbol(symbol)
1333            .interval(interval)
1334    }
1335}
1336/// Request parameters for the [`reference_price`] operation.
1337///
1338/// This struct holds all of the inputs you can pass when calling
1339/// [`reference_price`](#method.reference_price).
1340#[derive(Clone, Debug, Builder)]
1341#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1342pub struct ReferencePriceParams {
1343    ///
1344    /// The `symbol` parameter.
1345    ///
1346    /// This field is **required.
1347    #[builder(setter(into))]
1348    pub symbol: String,
1349}
1350
1351impl ReferencePriceParams {
1352    /// Create a builder for [`reference_price`].
1353    ///
1354    /// Required parameters:
1355    ///
1356    /// * `symbol` — String
1357    ///
1358    #[must_use]
1359    pub fn builder(symbol: String) -> ReferencePriceParamsBuilder {
1360        ReferencePriceParamsBuilder::default().symbol(symbol)
1361    }
1362}
1363/// Request parameters for the [`reference_price_calculation`] operation.
1364///
1365/// This struct holds all of the inputs you can pass when calling
1366/// [`reference_price_calculation`](#method.reference_price_calculation).
1367#[derive(Clone, Debug, Builder)]
1368#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1369pub struct ReferencePriceCalculationParams {
1370    ///
1371    /// The `symbol` parameter.
1372    ///
1373    /// This field is **required.
1374    #[builder(setter(into))]
1375    pub symbol: String,
1376    ///
1377    /// The `symbol_status` parameter.
1378    ///
1379    /// This field is **optional.
1380    #[builder(setter(into), default)]
1381    pub symbol_status: Option<ReferencePriceCalculationSymbolStatusEnum>,
1382}
1383
1384impl ReferencePriceCalculationParams {
1385    /// Create a builder for [`reference_price_calculation`].
1386    ///
1387    /// Required parameters:
1388    ///
1389    /// * `symbol` — String
1390    ///
1391    #[must_use]
1392    pub fn builder(symbol: String) -> ReferencePriceCalculationParamsBuilder {
1393        ReferencePriceCalculationParamsBuilder::default().symbol(symbol)
1394    }
1395}
1396/// Request parameters for the [`ticker`] operation.
1397///
1398/// This struct holds all of the inputs you can pass when calling
1399/// [`ticker`](#method.ticker).
1400#[derive(Clone, Debug, Builder, Default)]
1401#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1402pub struct TickerParams {
1403    /// Symbol to query
1404    ///
1405    /// This field is **optional.
1406    #[builder(setter(into), default)]
1407    pub symbol: Option<String>,
1408    /// List of symbols to query
1409    ///
1410    /// This field is **optional.
1411    #[builder(setter(into), default)]
1412    pub symbols: Option<Vec<String>>,
1413    ///
1414    /// The `window_size` parameter.
1415    ///
1416    /// This field is **optional.
1417    #[builder(setter(into), default)]
1418    pub window_size: Option<TickerWindowSizeEnum>,
1419    ///
1420    /// The `r#type` parameter.
1421    ///
1422    /// This field is **optional.
1423    #[builder(setter(into), default)]
1424    pub r#type: Option<TickerTypeEnum>,
1425    ///
1426    /// The `symbol_status` parameter.
1427    ///
1428    /// This field is **optional.
1429    #[builder(setter(into), default)]
1430    pub symbol_status: Option<TickerSymbolStatusEnum>,
1431}
1432
1433impl TickerParams {
1434    /// Create a builder for [`ticker`].
1435    ///
1436    #[must_use]
1437    pub fn builder() -> TickerParamsBuilder {
1438        TickerParamsBuilder::default()
1439    }
1440}
1441/// Request parameters for the [`ticker24hr`] operation.
1442///
1443/// This struct holds all of the inputs you can pass when calling
1444/// [`ticker24hr`](#method.ticker24hr).
1445#[derive(Clone, Debug, Builder, Default)]
1446#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1447pub struct Ticker24hrParams {
1448    /// Symbol to query
1449    ///
1450    /// This field is **optional.
1451    #[builder(setter(into), default)]
1452    pub symbol: Option<String>,
1453    /// List of symbols to query
1454    ///
1455    /// This field is **optional.
1456    #[builder(setter(into), default)]
1457    pub symbols: Option<Vec<String>>,
1458    ///
1459    /// The `r#type` parameter.
1460    ///
1461    /// This field is **optional.
1462    #[builder(setter(into), default)]
1463    pub r#type: Option<Ticker24hrTypeEnum>,
1464    ///
1465    /// The `symbol_status` parameter.
1466    ///
1467    /// This field is **optional.
1468    #[builder(setter(into), default)]
1469    pub symbol_status: Option<Ticker24hrSymbolStatusEnum>,
1470}
1471
1472impl Ticker24hrParams {
1473    /// Create a builder for [`ticker24hr`].
1474    ///
1475    #[must_use]
1476    pub fn builder() -> Ticker24hrParamsBuilder {
1477        Ticker24hrParamsBuilder::default()
1478    }
1479}
1480/// Request parameters for the [`ticker_book_ticker`] operation.
1481///
1482/// This struct holds all of the inputs you can pass when calling
1483/// [`ticker_book_ticker`](#method.ticker_book_ticker).
1484#[derive(Clone, Debug, Builder, Default)]
1485#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1486pub struct TickerBookTickerParams {
1487    /// Symbol to query
1488    ///
1489    /// This field is **optional.
1490    #[builder(setter(into), default)]
1491    pub symbol: Option<String>,
1492    /// List of symbols to query
1493    ///
1494    /// This field is **optional.
1495    #[builder(setter(into), default)]
1496    pub symbols: Option<Vec<String>>,
1497    ///
1498    /// The `symbol_status` parameter.
1499    ///
1500    /// This field is **optional.
1501    #[builder(setter(into), default)]
1502    pub symbol_status: Option<TickerBookTickerSymbolStatusEnum>,
1503}
1504
1505impl TickerBookTickerParams {
1506    /// Create a builder for [`ticker_book_ticker`].
1507    ///
1508    #[must_use]
1509    pub fn builder() -> TickerBookTickerParamsBuilder {
1510        TickerBookTickerParamsBuilder::default()
1511    }
1512}
1513/// Request parameters for the [`ticker_price`] operation.
1514///
1515/// This struct holds all of the inputs you can pass when calling
1516/// [`ticker_price`](#method.ticker_price).
1517#[derive(Clone, Debug, Builder, Default)]
1518#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1519pub struct TickerPriceParams {
1520    /// Symbol to query
1521    ///
1522    /// This field is **optional.
1523    #[builder(setter(into), default)]
1524    pub symbol: Option<String>,
1525    /// List of symbols to query
1526    ///
1527    /// This field is **optional.
1528    #[builder(setter(into), default)]
1529    pub symbols: Option<Vec<String>>,
1530    ///
1531    /// The `symbol_status` parameter.
1532    ///
1533    /// This field is **optional.
1534    #[builder(setter(into), default)]
1535    pub symbol_status: Option<TickerPriceSymbolStatusEnum>,
1536}
1537
1538impl TickerPriceParams {
1539    /// Create a builder for [`ticker_price`].
1540    ///
1541    #[must_use]
1542    pub fn builder() -> TickerPriceParamsBuilder {
1543        TickerPriceParamsBuilder::default()
1544    }
1545}
1546/// Request parameters for the [`ticker_trading_day`] operation.
1547///
1548/// This struct holds all of the inputs you can pass when calling
1549/// [`ticker_trading_day`](#method.ticker_trading_day).
1550#[derive(Clone, Debug, Builder, Default)]
1551#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1552pub struct TickerTradingDayParams {
1553    /// Symbol to query
1554    ///
1555    /// This field is **optional.
1556    #[builder(setter(into), default)]
1557    pub symbol: Option<String>,
1558    /// List of symbols to query
1559    ///
1560    /// This field is **optional.
1561    #[builder(setter(into), default)]
1562    pub symbols: Option<Vec<String>>,
1563    /// Default: 0 (UTC)
1564    ///
1565    /// This field is **optional.
1566    #[builder(setter(into), default)]
1567    pub time_zone: Option<String>,
1568    ///
1569    /// The `r#type` parameter.
1570    ///
1571    /// This field is **optional.
1572    #[builder(setter(into), default)]
1573    pub r#type: Option<TickerTradingDayTypeEnum>,
1574    ///
1575    /// The `symbol_status` parameter.
1576    ///
1577    /// This field is **optional.
1578    #[builder(setter(into), default)]
1579    pub symbol_status: Option<TickerTradingDaySymbolStatusEnum>,
1580}
1581
1582impl TickerTradingDayParams {
1583    /// Create a builder for [`ticker_trading_day`].
1584    ///
1585    #[must_use]
1586    pub fn builder() -> TickerTradingDayParamsBuilder {
1587        TickerTradingDayParamsBuilder::default()
1588    }
1589}
1590/// Request parameters for the [`ui_klines`] operation.
1591///
1592/// This struct holds all of the inputs you can pass when calling
1593/// [`ui_klines`](#method.ui_klines).
1594#[derive(Clone, Debug, Builder)]
1595#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1596pub struct UiKlinesParams {
1597    ///
1598    /// The `symbol` parameter.
1599    ///
1600    /// This field is **required.
1601    #[builder(setter(into))]
1602    pub symbol: String,
1603    ///
1604    /// The `interval` parameter.
1605    ///
1606    /// This field is **required.
1607    #[builder(setter(into))]
1608    pub interval: UiKlinesIntervalEnum,
1609    /// Timestamp in ms to get aggregate trades from INCLUSIVE.
1610    ///
1611    /// This field is **optional.
1612    #[builder(setter(into), default)]
1613    pub start_time: Option<i64>,
1614    /// Timestamp in ms to get aggregate trades until INCLUSIVE.
1615    ///
1616    /// This field is **optional.
1617    #[builder(setter(into), default)]
1618    pub end_time: Option<i64>,
1619    /// Default: 0 (UTC)
1620    ///
1621    /// This field is **optional.
1622    #[builder(setter(into), default)]
1623    pub time_zone: Option<String>,
1624    /// Default: 500; Maximum: 1000.
1625    ///
1626    /// This field is **optional.
1627    #[builder(setter(into), default)]
1628    pub limit: Option<i32>,
1629}
1630
1631impl UiKlinesParams {
1632    /// Create a builder for [`ui_klines`].
1633    ///
1634    /// Required parameters:
1635    ///
1636    /// * `symbol` — String
1637    /// * `interval` — String
1638    ///
1639    #[must_use]
1640    pub fn builder(symbol: String, interval: UiKlinesIntervalEnum) -> UiKlinesParamsBuilder {
1641        UiKlinesParamsBuilder::default()
1642            .symbol(symbol)
1643            .interval(interval)
1644    }
1645}
1646
1647#[async_trait]
1648impl MarketApi for MarketApiClient {
1649    async fn agg_trades(
1650        &self,
1651        params: AggTradesParams,
1652    ) -> anyhow::Result<RestApiResponse<Vec<models::AggTradesResponseInner>>> {
1653        let AggTradesParams {
1654            symbol,
1655            from_id,
1656            start_time,
1657            end_time,
1658            limit,
1659        } = params;
1660
1661        let mut query_params = BTreeMap::new();
1662        let body_params = BTreeMap::new();
1663
1664        query_params.insert("symbol".to_string(), json!(symbol));
1665
1666        if let Some(rw) = from_id {
1667            query_params.insert("fromId".to_string(), json!(rw));
1668        }
1669
1670        if let Some(rw) = start_time {
1671            query_params.insert("startTime".to_string(), json!(rw));
1672        }
1673
1674        if let Some(rw) = end_time {
1675            query_params.insert("endTime".to_string(), json!(rw));
1676        }
1677
1678        if let Some(rw) = limit {
1679            query_params.insert("limit".to_string(), json!(rw));
1680        }
1681
1682        send_request::<Vec<models::AggTradesResponseInner>>(
1683            &self.configuration,
1684            "/api/v3/aggTrades",
1685            reqwest::Method::GET,
1686            query_params,
1687            body_params,
1688            if HAS_TIME_UNIT {
1689                self.configuration.time_unit
1690            } else {
1691                None
1692            },
1693            false,
1694        )
1695        .await
1696    }
1697
1698    async fn avg_price(
1699        &self,
1700        params: AvgPriceParams,
1701    ) -> anyhow::Result<RestApiResponse<models::AvgPriceResponse>> {
1702        let AvgPriceParams { symbol } = params;
1703
1704        let mut query_params = BTreeMap::new();
1705        let body_params = BTreeMap::new();
1706
1707        query_params.insert("symbol".to_string(), json!(symbol));
1708
1709        send_request::<models::AvgPriceResponse>(
1710            &self.configuration,
1711            "/api/v3/avgPrice",
1712            reqwest::Method::GET,
1713            query_params,
1714            body_params,
1715            if HAS_TIME_UNIT {
1716                self.configuration.time_unit
1717            } else {
1718                None
1719            },
1720            false,
1721        )
1722        .await
1723    }
1724
1725    async fn depth(
1726        &self,
1727        params: DepthParams,
1728    ) -> anyhow::Result<RestApiResponse<models::DepthResponse>> {
1729        let DepthParams {
1730            symbol,
1731            limit,
1732            symbol_status,
1733        } = params;
1734
1735        let mut query_params = BTreeMap::new();
1736        let body_params = BTreeMap::new();
1737
1738        query_params.insert("symbol".to_string(), json!(symbol));
1739
1740        if let Some(rw) = limit {
1741            query_params.insert("limit".to_string(), json!(rw));
1742        }
1743
1744        if let Some(rw) = symbol_status {
1745            query_params.insert("symbolStatus".to_string(), json!(rw));
1746        }
1747
1748        send_request::<models::DepthResponse>(
1749            &self.configuration,
1750            "/api/v3/depth",
1751            reqwest::Method::GET,
1752            query_params,
1753            body_params,
1754            if HAS_TIME_UNIT {
1755                self.configuration.time_unit
1756            } else {
1757                None
1758            },
1759            false,
1760        )
1761        .await
1762    }
1763
1764    async fn get_trades(
1765        &self,
1766        params: GetTradesParams,
1767    ) -> anyhow::Result<RestApiResponse<Vec<models::HistoricalTradesResponseInner>>> {
1768        let GetTradesParams { symbol, limit } = params;
1769
1770        let mut query_params = BTreeMap::new();
1771        let body_params = BTreeMap::new();
1772
1773        query_params.insert("symbol".to_string(), json!(symbol));
1774
1775        if let Some(rw) = limit {
1776            query_params.insert("limit".to_string(), json!(rw));
1777        }
1778
1779        send_request::<Vec<models::HistoricalTradesResponseInner>>(
1780            &self.configuration,
1781            "/api/v3/trades",
1782            reqwest::Method::GET,
1783            query_params,
1784            body_params,
1785            if HAS_TIME_UNIT {
1786                self.configuration.time_unit
1787            } else {
1788                None
1789            },
1790            false,
1791        )
1792        .await
1793    }
1794
1795    async fn historical_block_trades(
1796        &self,
1797        params: HistoricalBlockTradesParams,
1798    ) -> anyhow::Result<RestApiResponse<Vec<models::HistoricalBlockTradesResponseInner>>> {
1799        let HistoricalBlockTradesParams {
1800            symbol,
1801            from_id,
1802            limit,
1803        } = params;
1804
1805        let mut query_params = BTreeMap::new();
1806        let body_params = BTreeMap::new();
1807
1808        query_params.insert("symbol".to_string(), json!(symbol));
1809
1810        query_params.insert("fromId".to_string(), json!(from_id));
1811
1812        if let Some(rw) = limit {
1813            query_params.insert("limit".to_string(), json!(rw));
1814        }
1815
1816        send_request::<Vec<models::HistoricalBlockTradesResponseInner>>(
1817            &self.configuration,
1818            "/api/v3/historicalBlockTrades",
1819            reqwest::Method::GET,
1820            query_params,
1821            body_params,
1822            if HAS_TIME_UNIT {
1823                self.configuration.time_unit
1824            } else {
1825                None
1826            },
1827            false,
1828        )
1829        .await
1830    }
1831
1832    async fn historical_trades(
1833        &self,
1834        params: HistoricalTradesParams,
1835    ) -> anyhow::Result<RestApiResponse<Vec<models::HistoricalTradesResponseInner>>> {
1836        let HistoricalTradesParams {
1837            symbol,
1838            limit,
1839            from_id,
1840        } = params;
1841
1842        let mut query_params = BTreeMap::new();
1843        let body_params = BTreeMap::new();
1844
1845        query_params.insert("symbol".to_string(), json!(symbol));
1846
1847        if let Some(rw) = limit {
1848            query_params.insert("limit".to_string(), json!(rw));
1849        }
1850
1851        if let Some(rw) = from_id {
1852            query_params.insert("fromId".to_string(), json!(rw));
1853        }
1854
1855        send_request::<Vec<models::HistoricalTradesResponseInner>>(
1856            &self.configuration,
1857            "/api/v3/historicalTrades",
1858            reqwest::Method::GET,
1859            query_params,
1860            body_params,
1861            if HAS_TIME_UNIT {
1862                self.configuration.time_unit
1863            } else {
1864                None
1865            },
1866            false,
1867        )
1868        .await
1869    }
1870
1871    async fn klines(
1872        &self,
1873        params: KlinesParams,
1874    ) -> anyhow::Result<RestApiResponse<Vec<Vec<models::KlinesItemInner>>>> {
1875        let KlinesParams {
1876            symbol,
1877            interval,
1878            start_time,
1879            end_time,
1880            time_zone,
1881            limit,
1882        } = params;
1883
1884        let mut query_params = BTreeMap::new();
1885        let body_params = BTreeMap::new();
1886
1887        query_params.insert("symbol".to_string(), json!(symbol));
1888
1889        query_params.insert("interval".to_string(), json!(interval));
1890
1891        if let Some(rw) = start_time {
1892            query_params.insert("startTime".to_string(), json!(rw));
1893        }
1894
1895        if let Some(rw) = end_time {
1896            query_params.insert("endTime".to_string(), json!(rw));
1897        }
1898
1899        if let Some(rw) = time_zone {
1900            query_params.insert("timeZone".to_string(), json!(rw));
1901        }
1902
1903        if let Some(rw) = limit {
1904            query_params.insert("limit".to_string(), json!(rw));
1905        }
1906
1907        send_request::<Vec<Vec<models::KlinesItemInner>>>(
1908            &self.configuration,
1909            "/api/v3/klines",
1910            reqwest::Method::GET,
1911            query_params,
1912            body_params,
1913            if HAS_TIME_UNIT {
1914                self.configuration.time_unit
1915            } else {
1916                None
1917            },
1918            false,
1919        )
1920        .await
1921    }
1922
1923    async fn reference_price(
1924        &self,
1925        params: ReferencePriceParams,
1926    ) -> anyhow::Result<RestApiResponse<models::ReferencePriceResponse>> {
1927        let ReferencePriceParams { symbol } = params;
1928
1929        let mut query_params = BTreeMap::new();
1930        let body_params = BTreeMap::new();
1931
1932        query_params.insert("symbol".to_string(), json!(symbol));
1933
1934        send_request::<models::ReferencePriceResponse>(
1935            &self.configuration,
1936            "/api/v3/referencePrice",
1937            reqwest::Method::GET,
1938            query_params,
1939            body_params,
1940            if HAS_TIME_UNIT {
1941                self.configuration.time_unit
1942            } else {
1943                None
1944            },
1945            false,
1946        )
1947        .await
1948    }
1949
1950    async fn reference_price_calculation(
1951        &self,
1952        params: ReferencePriceCalculationParams,
1953    ) -> anyhow::Result<RestApiResponse<models::ReferencePriceCalculationResponse>> {
1954        let ReferencePriceCalculationParams {
1955            symbol,
1956            symbol_status,
1957        } = params;
1958
1959        let mut query_params = BTreeMap::new();
1960        let body_params = BTreeMap::new();
1961
1962        query_params.insert("symbol".to_string(), json!(symbol));
1963
1964        if let Some(rw) = symbol_status {
1965            query_params.insert("symbolStatus".to_string(), json!(rw));
1966        }
1967
1968        send_request::<models::ReferencePriceCalculationResponse>(
1969            &self.configuration,
1970            "/api/v3/referencePrice/calculation",
1971            reqwest::Method::GET,
1972            query_params,
1973            body_params,
1974            if HAS_TIME_UNIT {
1975                self.configuration.time_unit
1976            } else {
1977                None
1978            },
1979            false,
1980        )
1981        .await
1982    }
1983
1984    async fn ticker(
1985        &self,
1986        params: TickerParams,
1987    ) -> anyhow::Result<RestApiResponse<models::TickerResponse>> {
1988        let TickerParams {
1989            symbol,
1990            symbols,
1991            window_size,
1992            r#type,
1993            symbol_status,
1994        } = params;
1995
1996        let mut query_params = BTreeMap::new();
1997        let body_params = BTreeMap::new();
1998
1999        if let Some(rw) = symbol {
2000            query_params.insert("symbol".to_string(), json!(rw));
2001        }
2002
2003        if let Some(rw) = symbols {
2004            query_params.insert("symbols".to_string(), json!(rw));
2005        }
2006
2007        if let Some(rw) = window_size {
2008            query_params.insert("windowSize".to_string(), json!(rw));
2009        }
2010
2011        if let Some(rw) = r#type {
2012            query_params.insert("type".to_string(), json!(rw));
2013        }
2014
2015        if let Some(rw) = symbol_status {
2016            query_params.insert("symbolStatus".to_string(), json!(rw));
2017        }
2018
2019        send_request::<models::TickerResponse>(
2020            &self.configuration,
2021            "/api/v3/ticker",
2022            reqwest::Method::GET,
2023            query_params,
2024            body_params,
2025            if HAS_TIME_UNIT {
2026                self.configuration.time_unit
2027            } else {
2028                None
2029            },
2030            false,
2031        )
2032        .await
2033    }
2034
2035    async fn ticker24hr(
2036        &self,
2037        params: Ticker24hrParams,
2038    ) -> anyhow::Result<RestApiResponse<models::Ticker24hrResponse>> {
2039        let Ticker24hrParams {
2040            symbol,
2041            symbols,
2042            r#type,
2043            symbol_status,
2044        } = params;
2045
2046        let mut query_params = BTreeMap::new();
2047        let body_params = BTreeMap::new();
2048
2049        if let Some(rw) = symbol {
2050            query_params.insert("symbol".to_string(), json!(rw));
2051        }
2052
2053        if let Some(rw) = symbols {
2054            query_params.insert("symbols".to_string(), json!(rw));
2055        }
2056
2057        if let Some(rw) = r#type {
2058            query_params.insert("type".to_string(), json!(rw));
2059        }
2060
2061        if let Some(rw) = symbol_status {
2062            query_params.insert("symbolStatus".to_string(), json!(rw));
2063        }
2064
2065        send_request::<models::Ticker24hrResponse>(
2066            &self.configuration,
2067            "/api/v3/ticker/24hr",
2068            reqwest::Method::GET,
2069            query_params,
2070            body_params,
2071            if HAS_TIME_UNIT {
2072                self.configuration.time_unit
2073            } else {
2074                None
2075            },
2076            false,
2077        )
2078        .await
2079    }
2080
2081    async fn ticker_book_ticker(
2082        &self,
2083        params: TickerBookTickerParams,
2084    ) -> anyhow::Result<RestApiResponse<models::TickerBookTickerResponse>> {
2085        let TickerBookTickerParams {
2086            symbol,
2087            symbols,
2088            symbol_status,
2089        } = params;
2090
2091        let mut query_params = BTreeMap::new();
2092        let body_params = BTreeMap::new();
2093
2094        if let Some(rw) = symbol {
2095            query_params.insert("symbol".to_string(), json!(rw));
2096        }
2097
2098        if let Some(rw) = symbols {
2099            query_params.insert("symbols".to_string(), json!(rw));
2100        }
2101
2102        if let Some(rw) = symbol_status {
2103            query_params.insert("symbolStatus".to_string(), json!(rw));
2104        }
2105
2106        send_request::<models::TickerBookTickerResponse>(
2107            &self.configuration,
2108            "/api/v3/ticker/bookTicker",
2109            reqwest::Method::GET,
2110            query_params,
2111            body_params,
2112            if HAS_TIME_UNIT {
2113                self.configuration.time_unit
2114            } else {
2115                None
2116            },
2117            false,
2118        )
2119        .await
2120    }
2121
2122    async fn ticker_price(
2123        &self,
2124        params: TickerPriceParams,
2125    ) -> anyhow::Result<RestApiResponse<models::TickerPriceResponse>> {
2126        let TickerPriceParams {
2127            symbol,
2128            symbols,
2129            symbol_status,
2130        } = params;
2131
2132        let mut query_params = BTreeMap::new();
2133        let body_params = BTreeMap::new();
2134
2135        if let Some(rw) = symbol {
2136            query_params.insert("symbol".to_string(), json!(rw));
2137        }
2138
2139        if let Some(rw) = symbols {
2140            query_params.insert("symbols".to_string(), json!(rw));
2141        }
2142
2143        if let Some(rw) = symbol_status {
2144            query_params.insert("symbolStatus".to_string(), json!(rw));
2145        }
2146
2147        send_request::<models::TickerPriceResponse>(
2148            &self.configuration,
2149            "/api/v3/ticker/price",
2150            reqwest::Method::GET,
2151            query_params,
2152            body_params,
2153            if HAS_TIME_UNIT {
2154                self.configuration.time_unit
2155            } else {
2156                None
2157            },
2158            false,
2159        )
2160        .await
2161    }
2162
2163    async fn ticker_trading_day(
2164        &self,
2165        params: TickerTradingDayParams,
2166    ) -> anyhow::Result<RestApiResponse<models::TickerTradingDayResponse>> {
2167        let TickerTradingDayParams {
2168            symbol,
2169            symbols,
2170            time_zone,
2171            r#type,
2172            symbol_status,
2173        } = params;
2174
2175        let mut query_params = BTreeMap::new();
2176        let body_params = BTreeMap::new();
2177
2178        if let Some(rw) = symbol {
2179            query_params.insert("symbol".to_string(), json!(rw));
2180        }
2181
2182        if let Some(rw) = symbols {
2183            query_params.insert("symbols".to_string(), json!(rw));
2184        }
2185
2186        if let Some(rw) = time_zone {
2187            query_params.insert("timeZone".to_string(), json!(rw));
2188        }
2189
2190        if let Some(rw) = r#type {
2191            query_params.insert("type".to_string(), json!(rw));
2192        }
2193
2194        if let Some(rw) = symbol_status {
2195            query_params.insert("symbolStatus".to_string(), json!(rw));
2196        }
2197
2198        send_request::<models::TickerTradingDayResponse>(
2199            &self.configuration,
2200            "/api/v3/ticker/tradingDay",
2201            reqwest::Method::GET,
2202            query_params,
2203            body_params,
2204            if HAS_TIME_UNIT {
2205                self.configuration.time_unit
2206            } else {
2207                None
2208            },
2209            false,
2210        )
2211        .await
2212    }
2213
2214    async fn ui_klines(
2215        &self,
2216        params: UiKlinesParams,
2217    ) -> anyhow::Result<RestApiResponse<Vec<Vec<models::KlinesItemInner>>>> {
2218        let UiKlinesParams {
2219            symbol,
2220            interval,
2221            start_time,
2222            end_time,
2223            time_zone,
2224            limit,
2225        } = params;
2226
2227        let mut query_params = BTreeMap::new();
2228        let body_params = BTreeMap::new();
2229
2230        query_params.insert("symbol".to_string(), json!(symbol));
2231
2232        query_params.insert("interval".to_string(), json!(interval));
2233
2234        if let Some(rw) = start_time {
2235            query_params.insert("startTime".to_string(), json!(rw));
2236        }
2237
2238        if let Some(rw) = end_time {
2239            query_params.insert("endTime".to_string(), json!(rw));
2240        }
2241
2242        if let Some(rw) = time_zone {
2243            query_params.insert("timeZone".to_string(), json!(rw));
2244        }
2245
2246        if let Some(rw) = limit {
2247            query_params.insert("limit".to_string(), json!(rw));
2248        }
2249
2250        send_request::<Vec<Vec<models::KlinesItemInner>>>(
2251            &self.configuration,
2252            "/api/v3/uiKlines",
2253            reqwest::Method::GET,
2254            query_params,
2255            body_params,
2256            if HAS_TIME_UNIT {
2257                self.configuration.time_unit
2258            } else {
2259                None
2260            },
2261            false,
2262        )
2263        .await
2264    }
2265}
2266
2267#[cfg(all(test, feature = "spot"))]
2268mod tests {
2269    use super::*;
2270    use crate::TOKIO_SHARED_RT;
2271    use crate::{errors::ConnectorError, models::DataFuture, models::RestApiRateLimit};
2272    use async_trait::async_trait;
2273    use std::collections::HashMap;
2274
2275    struct DummyRestApiResponse<T> {
2276        inner: Box<dyn FnOnce() -> DataFuture<Result<T, ConnectorError>> + Send + Sync>,
2277        status: u16,
2278        headers: HashMap<String, String>,
2279        rate_limits: Option<Vec<RestApiRateLimit>>,
2280    }
2281
2282    impl<T> From<DummyRestApiResponse<T>> for RestApiResponse<T> {
2283        fn from(dummy: DummyRestApiResponse<T>) -> Self {
2284            Self {
2285                data_fn: dummy.inner,
2286                status: dummy.status,
2287                headers: dummy.headers,
2288                rate_limits: dummy.rate_limits,
2289            }
2290        }
2291    }
2292
2293    struct MockMarketApiClient {
2294        force_error: bool,
2295    }
2296
2297    #[async_trait]
2298    impl MarketApi for MockMarketApiClient {
2299        async fn agg_trades(
2300            &self,
2301            _params: AggTradesParams,
2302        ) -> anyhow::Result<RestApiResponse<Vec<models::AggTradesResponseInner>>> {
2303            if self.force_error {
2304                return Err(ConnectorError::ConnectorClientError {
2305                    msg: "ResponseError".to_string(),
2306                    code: None,
2307                }
2308                .into());
2309            }
2310
2311            let resp_json: Value = serde_json::from_str(r#"[{"a":26129,"p":"0.01633102","q":"4.70443515","f":27781,"l":27781,"T":1498793709153,"m":true,"M":true}]"#).unwrap();
2312            let dummy_response: Vec<models::AggTradesResponseInner> =
2313                serde_json::from_value(resp_json.clone())
2314                    .expect("should parse into Vec<models::AggTradesResponseInner>");
2315
2316            let dummy = DummyRestApiResponse {
2317                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2318                status: 200,
2319                headers: HashMap::new(),
2320                rate_limits: None,
2321            };
2322
2323            Ok(dummy.into())
2324        }
2325
2326        async fn avg_price(
2327            &self,
2328            _params: AvgPriceParams,
2329        ) -> anyhow::Result<RestApiResponse<models::AvgPriceResponse>> {
2330            if self.force_error {
2331                return Err(ConnectorError::ConnectorClientError {
2332                    msg: "ResponseError".to_string(),
2333                    code: None,
2334                }
2335                .into());
2336            }
2337
2338            let resp_json: Value = serde_json::from_str(
2339                r#"{"mins":5,"price":"9.35751834","closeTime":1694061154503}"#,
2340            )
2341            .unwrap();
2342            let dummy_response: models::AvgPriceResponse =
2343                serde_json::from_value(resp_json.clone())
2344                    .expect("should parse into models::AvgPriceResponse");
2345
2346            let dummy = DummyRestApiResponse {
2347                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2348                status: 200,
2349                headers: HashMap::new(),
2350                rate_limits: None,
2351            };
2352
2353            Ok(dummy.into())
2354        }
2355
2356        async fn depth(
2357            &self,
2358            _params: DepthParams,
2359        ) -> anyhow::Result<RestApiResponse<models::DepthResponse>> {
2360            if self.force_error {
2361                return Err(ConnectorError::ConnectorClientError {
2362                    msg: "ResponseError".to_string(),
2363                    code: None,
2364                }
2365                .into());
2366            }
2367
2368            let resp_json: Value = serde_json::from_str(r#"{"lastUpdateId":1027024,"bids":[["4.00000000","431.00000000"]],"asks":[["4.00000200","12.00000000"]]}"#).unwrap();
2369            let dummy_response: models::DepthResponse = serde_json::from_value(resp_json.clone())
2370                .expect("should parse into models::DepthResponse");
2371
2372            let dummy = DummyRestApiResponse {
2373                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2374                status: 200,
2375                headers: HashMap::new(),
2376                rate_limits: None,
2377            };
2378
2379            Ok(dummy.into())
2380        }
2381
2382        async fn get_trades(
2383            &self,
2384            _params: GetTradesParams,
2385        ) -> anyhow::Result<RestApiResponse<Vec<models::HistoricalTradesResponseInner>>> {
2386            if self.force_error {
2387                return Err(ConnectorError::ConnectorClientError {
2388                    msg: "ResponseError".to_string(),
2389                    code: None,
2390                }
2391                .into());
2392            }
2393
2394            let resp_json: Value = serde_json::from_str(r#"[{"id":28457,"price":"4.00000100","qty":"12.00000000","quoteQty":"48.000012","time":1499865549590,"isBuyerMaker":true,"isBestMatch":true}]"#).unwrap();
2395            let dummy_response: Vec<models::HistoricalTradesResponseInner> =
2396                serde_json::from_value(resp_json.clone())
2397                    .expect("should parse into Vec<models::HistoricalTradesResponseInner>");
2398
2399            let dummy = DummyRestApiResponse {
2400                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2401                status: 200,
2402                headers: HashMap::new(),
2403                rate_limits: None,
2404            };
2405
2406            Ok(dummy.into())
2407        }
2408
2409        async fn historical_block_trades(
2410            &self,
2411            _params: HistoricalBlockTradesParams,
2412        ) -> anyhow::Result<RestApiResponse<Vec<models::HistoricalBlockTradesResponseInner>>>
2413        {
2414            if self.force_error {
2415                return Err(ConnectorError::ConnectorClientError {
2416                    msg: "ResponseError".to_string(),
2417                    code: None,
2418                }
2419                .into());
2420            }
2421
2422            let resp_json: Value = serde_json::from_str(r#"[{"id":582,"price":"0.052","qty":"5838","quoteQty":"303.576","time":1772506983321,"isBuyerMaker":true}]"#).unwrap();
2423            let dummy_response: Vec<models::HistoricalBlockTradesResponseInner> =
2424                serde_json::from_value(resp_json.clone())
2425                    .expect("should parse into Vec<models::HistoricalBlockTradesResponseInner>");
2426
2427            let dummy = DummyRestApiResponse {
2428                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2429                status: 200,
2430                headers: HashMap::new(),
2431                rate_limits: None,
2432            };
2433
2434            Ok(dummy.into())
2435        }
2436
2437        async fn historical_trades(
2438            &self,
2439            _params: HistoricalTradesParams,
2440        ) -> anyhow::Result<RestApiResponse<Vec<models::HistoricalTradesResponseInner>>> {
2441            if self.force_error {
2442                return Err(ConnectorError::ConnectorClientError {
2443                    msg: "ResponseError".to_string(),
2444                    code: None,
2445                }
2446                .into());
2447            }
2448
2449            let resp_json: Value = serde_json::from_str(r#"[{"id":28457,"price":"4.00000100","qty":"12.00000000","quoteQty":"48.000012","time":1499865549590,"isBuyerMaker":true,"isBestMatch":true}]"#).unwrap();
2450            let dummy_response: Vec<models::HistoricalTradesResponseInner> =
2451                serde_json::from_value(resp_json.clone())
2452                    .expect("should parse into Vec<models::HistoricalTradesResponseInner>");
2453
2454            let dummy = DummyRestApiResponse {
2455                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2456                status: 200,
2457                headers: HashMap::new(),
2458                rate_limits: None,
2459            };
2460
2461            Ok(dummy.into())
2462        }
2463
2464        async fn klines(
2465            &self,
2466            _params: KlinesParams,
2467        ) -> anyhow::Result<RestApiResponse<Vec<Vec<models::KlinesItemInner>>>> {
2468            if self.force_error {
2469                return Err(ConnectorError::ConnectorClientError {
2470                    msg: "ResponseError".to_string(),
2471                    code: None,
2472                }
2473                .into());
2474            }
2475
2476            let resp_json: Value = serde_json::from_str(r#"[[1499040000000,"0.01634790","0.80000000","0.01575800","0.01577100","148976.11427815",1499644799999,"2434.19055334",308,"1756.87402397","28.46694368","0"]]"#).unwrap();
2477            let dummy_response: Vec<Vec<models::KlinesItemInner>> =
2478                serde_json::from_value(resp_json.clone())
2479                    .expect("should parse into Vec<Vec<models::KlinesItemInner>>");
2480
2481            let dummy = DummyRestApiResponse {
2482                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2483                status: 200,
2484                headers: HashMap::new(),
2485                rate_limits: None,
2486            };
2487
2488            Ok(dummy.into())
2489        }
2490
2491        async fn reference_price(
2492            &self,
2493            _params: ReferencePriceParams,
2494        ) -> anyhow::Result<RestApiResponse<models::ReferencePriceResponse>> {
2495            if self.force_error {
2496                return Err(ConnectorError::ConnectorClientError {
2497                    msg: "ResponseError".to_string(),
2498                    code: None,
2499                }
2500                .into());
2501            }
2502
2503            let resp_json: Value = serde_json::from_str(
2504                r#"{"symbol":"BAZUSD","referencePrice":"10.00","timestamp":1770736694138}"#,
2505            )
2506            .unwrap();
2507            let dummy_response: models::ReferencePriceResponse =
2508                serde_json::from_value(resp_json.clone())
2509                    .expect("should parse into models::ReferencePriceResponse");
2510
2511            let dummy = DummyRestApiResponse {
2512                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2513                status: 200,
2514                headers: HashMap::new(),
2515                rate_limits: None,
2516            };
2517
2518            Ok(dummy.into())
2519        }
2520
2521        async fn reference_price_calculation(
2522            &self,
2523            _params: ReferencePriceCalculationParams,
2524        ) -> anyhow::Result<RestApiResponse<models::ReferencePriceCalculationResponse>> {
2525            if self.force_error {
2526                return Err(ConnectorError::ConnectorClientError {
2527                    msg: "ResponseError".to_string(),
2528                    code: None,
2529                }
2530                .into());
2531            }
2532
2533            let resp_json: Value = serde_json::from_str(r#"{"symbol":"BAZUSD","calculationType":"EXTERNAL","bucketCount":10,"bucketWidthMs":1000,"externalCalculationId":42}"#).unwrap();
2534            let dummy_response: models::ReferencePriceCalculationResponse =
2535                serde_json::from_value(resp_json.clone())
2536                    .expect("should parse into models::ReferencePriceCalculationResponse");
2537
2538            let dummy = DummyRestApiResponse {
2539                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2540                status: 200,
2541                headers: HashMap::new(),
2542                rate_limits: None,
2543            };
2544
2545            Ok(dummy.into())
2546        }
2547
2548        async fn ticker(
2549            &self,
2550            _params: TickerParams,
2551        ) -> anyhow::Result<RestApiResponse<models::TickerResponse>> {
2552            if self.force_error {
2553                return Err(ConnectorError::ConnectorClientError {
2554                    msg: "ResponseError".to_string(),
2555                    code: None,
2556                }
2557                .into());
2558            }
2559
2560            let resp_json: Value = serde_json::from_str(r#"{"symbol":"LTCBTC","priceChange":"-8.00000000","priceChangePercent":"-88.889","weightedAvgPrice":"2.60427807","openPrice":"0.10000000","highPrice":"2.00000000","lowPrice":"0.10000000","lastPrice":"2.00000000","volume":"39.00000000","quoteVolume":"13.40000000","openTime":1656986580000,"closeTime":1657001016795,"firstId":0,"lastId":34,"count":35}"#).unwrap();
2561            let dummy_response: models::TickerResponse = serde_json::from_value(resp_json.clone())
2562                .expect("should parse into models::TickerResponse");
2563
2564            let dummy = DummyRestApiResponse {
2565                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2566                status: 200,
2567                headers: HashMap::new(),
2568                rate_limits: None,
2569            };
2570
2571            Ok(dummy.into())
2572        }
2573
2574        async fn ticker24hr(
2575            &self,
2576            _params: Ticker24hrParams,
2577        ) -> anyhow::Result<RestApiResponse<models::Ticker24hrResponse>> {
2578            if self.force_error {
2579                return Err(ConnectorError::ConnectorClientError {
2580                    msg: "ResponseError".to_string(),
2581                    code: None,
2582                }
2583                .into());
2584            }
2585
2586            let resp_json: Value = serde_json::from_str(r#"{"symbol":"BNBBTC","priceChange":"-94.99999800","priceChangePercent":"-95.960","weightedAvgPrice":"0.29628482","prevClosePrice":"0.10002000","lastPrice":"4.00000200","lastQty":"200.00000000","bidPrice":"4.00000000","bidQty":"100.00000000","askPrice":"4.00000200","askQty":"100.00000000","openPrice":"99.00000000","highPrice":"100.00000000","lowPrice":"0.10000000","volume":"8913.30000000","quoteVolume":"15.30000000","openTime":1499783499040,"closeTime":1499869899040,"firstId":28385,"lastId":28460,"count":76}"#).unwrap();
2587            let dummy_response: models::Ticker24hrResponse =
2588                serde_json::from_value(resp_json.clone())
2589                    .expect("should parse into models::Ticker24hrResponse");
2590
2591            let dummy = DummyRestApiResponse {
2592                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2593                status: 200,
2594                headers: HashMap::new(),
2595                rate_limits: None,
2596            };
2597
2598            Ok(dummy.into())
2599        }
2600
2601        async fn ticker_book_ticker(
2602            &self,
2603            _params: TickerBookTickerParams,
2604        ) -> anyhow::Result<RestApiResponse<models::TickerBookTickerResponse>> {
2605            if self.force_error {
2606                return Err(ConnectorError::ConnectorClientError {
2607                    msg: "ResponseError".to_string(),
2608                    code: None,
2609                }
2610                .into());
2611            }
2612
2613            let resp_json: Value = serde_json::from_str(r#"{"symbol":"LTCBTC","bidPrice":"4.00000000","bidQty":"431.00000000","askPrice":"4.00000200","askQty":"9.00000000"}"#).unwrap();
2614            let dummy_response: models::TickerBookTickerResponse =
2615                serde_json::from_value(resp_json.clone())
2616                    .expect("should parse into models::TickerBookTickerResponse");
2617
2618            let dummy = DummyRestApiResponse {
2619                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2620                status: 200,
2621                headers: HashMap::new(),
2622                rate_limits: None,
2623            };
2624
2625            Ok(dummy.into())
2626        }
2627
2628        async fn ticker_price(
2629            &self,
2630            _params: TickerPriceParams,
2631        ) -> anyhow::Result<RestApiResponse<models::TickerPriceResponse>> {
2632            if self.force_error {
2633                return Err(ConnectorError::ConnectorClientError {
2634                    msg: "ResponseError".to_string(),
2635                    code: None,
2636                }
2637                .into());
2638            }
2639
2640            let resp_json: Value =
2641                serde_json::from_str(r#"{"symbol":"LTCBTC","price":"4.00000200"}"#).unwrap();
2642            let dummy_response: models::TickerPriceResponse =
2643                serde_json::from_value(resp_json.clone())
2644                    .expect("should parse into models::TickerPriceResponse");
2645
2646            let dummy = DummyRestApiResponse {
2647                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2648                status: 200,
2649                headers: HashMap::new(),
2650                rate_limits: None,
2651            };
2652
2653            Ok(dummy.into())
2654        }
2655
2656        async fn ticker_trading_day(
2657            &self,
2658            _params: TickerTradingDayParams,
2659        ) -> anyhow::Result<RestApiResponse<models::TickerTradingDayResponse>> {
2660            if self.force_error {
2661                return Err(ConnectorError::ConnectorClientError {
2662                    msg: "ResponseError".to_string(),
2663                    code: None,
2664                }
2665                .into());
2666            }
2667
2668            let resp_json: Value = serde_json::from_str(r#"{"symbol":"BTCUSDT","priceChange":"-83.13000000","priceChangePercent":"-0.317","weightedAvgPrice":"26234.58803036","openPrice":"26304.80000000","highPrice":"26397.46000000","lowPrice":"26088.34000000","lastPrice":"26221.67000000","volume":"18495.35066000","quoteVolume":"485217905.04210480","openTime":1695686400000,"closeTime":1695772799999,"firstId":3220151555,"lastId":3220849281,"count":697727}"#).unwrap();
2669            let dummy_response: models::TickerTradingDayResponse =
2670                serde_json::from_value(resp_json.clone())
2671                    .expect("should parse into models::TickerTradingDayResponse");
2672
2673            let dummy = DummyRestApiResponse {
2674                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2675                status: 200,
2676                headers: HashMap::new(),
2677                rate_limits: None,
2678            };
2679
2680            Ok(dummy.into())
2681        }
2682
2683        async fn ui_klines(
2684            &self,
2685            _params: UiKlinesParams,
2686        ) -> anyhow::Result<RestApiResponse<Vec<Vec<models::KlinesItemInner>>>> {
2687            if self.force_error {
2688                return Err(ConnectorError::ConnectorClientError {
2689                    msg: "ResponseError".to_string(),
2690                    code: None,
2691                }
2692                .into());
2693            }
2694
2695            let resp_json: Value = serde_json::from_str(r#"[[1499040000000,"0.01634790","0.80000000","0.01575800","0.01577100","148976.11427815",1499644799999,"2434.19055334",308,"1756.87402397","28.46694368","0"]]"#).unwrap();
2696            let dummy_response: Vec<Vec<models::KlinesItemInner>> =
2697                serde_json::from_value(resp_json.clone())
2698                    .expect("should parse into Vec<Vec<models::KlinesItemInner>>");
2699
2700            let dummy = DummyRestApiResponse {
2701                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2702                status: 200,
2703                headers: HashMap::new(),
2704                rate_limits: None,
2705            };
2706
2707            Ok(dummy.into())
2708        }
2709    }
2710
2711    #[test]
2712    fn agg_trades_required_params_success() {
2713        TOKIO_SHARED_RT.block_on(async {
2714            let client = MockMarketApiClient { force_error: false };
2715
2716            let params = AggTradesParams::builder("BNBUSDT".to_string(),).build().unwrap();
2717
2718            let resp_json: Value = serde_json::from_str(r#"[{"a":26129,"p":"0.01633102","q":"4.70443515","f":27781,"l":27781,"T":1498793709153,"m":true,"M":true}]"#).unwrap();
2719            let expected_response : Vec<models::AggTradesResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::AggTradesResponseInner>");
2720
2721            let resp = client.agg_trades(params).await.expect("Expected a response");
2722            let data_future = resp.data();
2723            let actual_response = data_future.await.unwrap();
2724            assert_eq!(actual_response, expected_response);
2725        });
2726    }
2727
2728    #[test]
2729    fn agg_trades_optional_params_success() {
2730        TOKIO_SHARED_RT.block_on(async {
2731            let client = MockMarketApiClient { force_error: false };
2732
2733            let params = AggTradesParams::builder("BNBUSDT".to_string(),).from_id(1).start_time(1735693200000).end_time(1735693200000).limit(500).build().unwrap();
2734
2735            let resp_json: Value = serde_json::from_str(r#"[{"a":26129,"p":"0.01633102","q":"4.70443515","f":27781,"l":27781,"T":1498793709153,"m":true,"M":true}]"#).unwrap();
2736            let expected_response : Vec<models::AggTradesResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::AggTradesResponseInner>");
2737
2738            let resp = client.agg_trades(params).await.expect("Expected a response");
2739            let data_future = resp.data();
2740            let actual_response = data_future.await.unwrap();
2741            assert_eq!(actual_response, expected_response);
2742        });
2743    }
2744
2745    #[test]
2746    fn agg_trades_response_error() {
2747        TOKIO_SHARED_RT.block_on(async {
2748            let client = MockMarketApiClient { force_error: true };
2749
2750            let params = AggTradesParams::builder("BNBUSDT".to_string())
2751                .build()
2752                .unwrap();
2753
2754            match client.agg_trades(params).await {
2755                Ok(_) => panic!("Expected an error"),
2756                Err(err) => {
2757                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
2758                }
2759            }
2760        });
2761    }
2762
2763    #[test]
2764    fn avg_price_required_params_success() {
2765        TOKIO_SHARED_RT.block_on(async {
2766            let client = MockMarketApiClient { force_error: false };
2767
2768            let params = AvgPriceParams::builder("BNBUSDT".to_string())
2769                .build()
2770                .unwrap();
2771
2772            let resp_json: Value = serde_json::from_str(
2773                r#"{"mins":5,"price":"9.35751834","closeTime":1694061154503}"#,
2774            )
2775            .unwrap();
2776            let expected_response: models::AvgPriceResponse =
2777                serde_json::from_value(resp_json.clone())
2778                    .expect("should parse into models::AvgPriceResponse");
2779
2780            let resp = client.avg_price(params).await.expect("Expected a response");
2781            let data_future = resp.data();
2782            let actual_response = data_future.await.unwrap();
2783            assert_eq!(actual_response, expected_response);
2784        });
2785    }
2786
2787    #[test]
2788    fn avg_price_optional_params_success() {
2789        TOKIO_SHARED_RT.block_on(async {
2790            let client = MockMarketApiClient { force_error: false };
2791
2792            let params = AvgPriceParams::builder("BNBUSDT".to_string())
2793                .build()
2794                .unwrap();
2795
2796            let resp_json: Value = serde_json::from_str(
2797                r#"{"mins":5,"price":"9.35751834","closeTime":1694061154503}"#,
2798            )
2799            .unwrap();
2800            let expected_response: models::AvgPriceResponse =
2801                serde_json::from_value(resp_json.clone())
2802                    .expect("should parse into models::AvgPriceResponse");
2803
2804            let resp = client.avg_price(params).await.expect("Expected a response");
2805            let data_future = resp.data();
2806            let actual_response = data_future.await.unwrap();
2807            assert_eq!(actual_response, expected_response);
2808        });
2809    }
2810
2811    #[test]
2812    fn avg_price_response_error() {
2813        TOKIO_SHARED_RT.block_on(async {
2814            let client = MockMarketApiClient { force_error: true };
2815
2816            let params = AvgPriceParams::builder("BNBUSDT".to_string())
2817                .build()
2818                .unwrap();
2819
2820            match client.avg_price(params).await {
2821                Ok(_) => panic!("Expected an error"),
2822                Err(err) => {
2823                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
2824                }
2825            }
2826        });
2827    }
2828
2829    #[test]
2830    fn depth_required_params_success() {
2831        TOKIO_SHARED_RT.block_on(async {
2832            let client = MockMarketApiClient { force_error: false };
2833
2834            let params = DepthParams::builder("BNBUSDT".to_string(),).build().unwrap();
2835
2836            let resp_json: Value = serde_json::from_str(r#"{"lastUpdateId":1027024,"bids":[["4.00000000","431.00000000"]],"asks":[["4.00000200","12.00000000"]]}"#).unwrap();
2837            let expected_response : models::DepthResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::DepthResponse");
2838
2839            let resp = client.depth(params).await.expect("Expected a response");
2840            let data_future = resp.data();
2841            let actual_response = data_future.await.unwrap();
2842            assert_eq!(actual_response, expected_response);
2843        });
2844    }
2845
2846    #[test]
2847    fn depth_optional_params_success() {
2848        TOKIO_SHARED_RT.block_on(async {
2849            let client = MockMarketApiClient { force_error: false };
2850
2851            let params = DepthParams::builder("BNBUSDT".to_string(),).limit(500).symbol_status(DepthSymbolStatusEnum::Trading).build().unwrap();
2852
2853            let resp_json: Value = serde_json::from_str(r#"{"lastUpdateId":1027024,"bids":[["4.00000000","431.00000000"]],"asks":[["4.00000200","12.00000000"]]}"#).unwrap();
2854            let expected_response : models::DepthResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::DepthResponse");
2855
2856            let resp = client.depth(params).await.expect("Expected a response");
2857            let data_future = resp.data();
2858            let actual_response = data_future.await.unwrap();
2859            assert_eq!(actual_response, expected_response);
2860        });
2861    }
2862
2863    #[test]
2864    fn depth_response_error() {
2865        TOKIO_SHARED_RT.block_on(async {
2866            let client = MockMarketApiClient { force_error: true };
2867
2868            let params = DepthParams::builder("BNBUSDT".to_string()).build().unwrap();
2869
2870            match client.depth(params).await {
2871                Ok(_) => panic!("Expected an error"),
2872                Err(err) => {
2873                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
2874                }
2875            }
2876        });
2877    }
2878
2879    #[test]
2880    fn get_trades_required_params_success() {
2881        TOKIO_SHARED_RT.block_on(async {
2882            let client = MockMarketApiClient { force_error: false };
2883
2884            let params = GetTradesParams::builder("BNBUSDT".to_string(),).build().unwrap();
2885
2886            let resp_json: Value = serde_json::from_str(r#"[{"id":28457,"price":"4.00000100","qty":"12.00000000","quoteQty":"48.000012","time":1499865549590,"isBuyerMaker":true,"isBestMatch":true}]"#).unwrap();
2887            let expected_response : Vec<models::HistoricalTradesResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::HistoricalTradesResponseInner>");
2888
2889            let resp = client.get_trades(params).await.expect("Expected a response");
2890            let data_future = resp.data();
2891            let actual_response = data_future.await.unwrap();
2892            assert_eq!(actual_response, expected_response);
2893        });
2894    }
2895
2896    #[test]
2897    fn get_trades_optional_params_success() {
2898        TOKIO_SHARED_RT.block_on(async {
2899            let client = MockMarketApiClient { force_error: false };
2900
2901            let params = GetTradesParams::builder("BNBUSDT".to_string(),).limit(500).build().unwrap();
2902
2903            let resp_json: Value = serde_json::from_str(r#"[{"id":28457,"price":"4.00000100","qty":"12.00000000","quoteQty":"48.000012","time":1499865549590,"isBuyerMaker":true,"isBestMatch":true}]"#).unwrap();
2904            let expected_response : Vec<models::HistoricalTradesResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::HistoricalTradesResponseInner>");
2905
2906            let resp = client.get_trades(params).await.expect("Expected a response");
2907            let data_future = resp.data();
2908            let actual_response = data_future.await.unwrap();
2909            assert_eq!(actual_response, expected_response);
2910        });
2911    }
2912
2913    #[test]
2914    fn get_trades_response_error() {
2915        TOKIO_SHARED_RT.block_on(async {
2916            let client = MockMarketApiClient { force_error: true };
2917
2918            let params = GetTradesParams::builder("BNBUSDT".to_string())
2919                .build()
2920                .unwrap();
2921
2922            match client.get_trades(params).await {
2923                Ok(_) => panic!("Expected an error"),
2924                Err(err) => {
2925                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
2926                }
2927            }
2928        });
2929    }
2930
2931    #[test]
2932    fn historical_block_trades_required_params_success() {
2933        TOKIO_SHARED_RT.block_on(async {
2934            let client = MockMarketApiClient { force_error: false };
2935
2936            let params = HistoricalBlockTradesParams::builder("BNBUSDT".to_string(),1,).build().unwrap();
2937
2938            let resp_json: Value = serde_json::from_str(r#"[{"id":582,"price":"0.052","qty":"5838","quoteQty":"303.576","time":1772506983321,"isBuyerMaker":true}]"#).unwrap();
2939            let expected_response : Vec<models::HistoricalBlockTradesResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::HistoricalBlockTradesResponseInner>");
2940
2941            let resp = client.historical_block_trades(params).await.expect("Expected a response");
2942            let data_future = resp.data();
2943            let actual_response = data_future.await.unwrap();
2944            assert_eq!(actual_response, expected_response);
2945        });
2946    }
2947
2948    #[test]
2949    fn historical_block_trades_optional_params_success() {
2950        TOKIO_SHARED_RT.block_on(async {
2951            let client = MockMarketApiClient { force_error: false };
2952
2953            let params = HistoricalBlockTradesParams::builder("BNBUSDT".to_string(),1,).limit(500).build().unwrap();
2954
2955            let resp_json: Value = serde_json::from_str(r#"[{"id":582,"price":"0.052","qty":"5838","quoteQty":"303.576","time":1772506983321,"isBuyerMaker":true}]"#).unwrap();
2956            let expected_response : Vec<models::HistoricalBlockTradesResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::HistoricalBlockTradesResponseInner>");
2957
2958            let resp = client.historical_block_trades(params).await.expect("Expected a response");
2959            let data_future = resp.data();
2960            let actual_response = data_future.await.unwrap();
2961            assert_eq!(actual_response, expected_response);
2962        });
2963    }
2964
2965    #[test]
2966    fn historical_block_trades_response_error() {
2967        TOKIO_SHARED_RT.block_on(async {
2968            let client = MockMarketApiClient { force_error: true };
2969
2970            let params = HistoricalBlockTradesParams::builder("BNBUSDT".to_string(), 1)
2971                .build()
2972                .unwrap();
2973
2974            match client.historical_block_trades(params).await {
2975                Ok(_) => panic!("Expected an error"),
2976                Err(err) => {
2977                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
2978                }
2979            }
2980        });
2981    }
2982
2983    #[test]
2984    fn historical_trades_required_params_success() {
2985        TOKIO_SHARED_RT.block_on(async {
2986            let client = MockMarketApiClient { force_error: false };
2987
2988            let params = HistoricalTradesParams::builder("BNBUSDT".to_string(),).build().unwrap();
2989
2990            let resp_json: Value = serde_json::from_str(r#"[{"id":28457,"price":"4.00000100","qty":"12.00000000","quoteQty":"48.000012","time":1499865549590,"isBuyerMaker":true,"isBestMatch":true}]"#).unwrap();
2991            let expected_response : Vec<models::HistoricalTradesResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::HistoricalTradesResponseInner>");
2992
2993            let resp = client.historical_trades(params).await.expect("Expected a response");
2994            let data_future = resp.data();
2995            let actual_response = data_future.await.unwrap();
2996            assert_eq!(actual_response, expected_response);
2997        });
2998    }
2999
3000    #[test]
3001    fn historical_trades_optional_params_success() {
3002        TOKIO_SHARED_RT.block_on(async {
3003            let client = MockMarketApiClient { force_error: false };
3004
3005            let params = HistoricalTradesParams::builder("BNBUSDT".to_string(),).limit(500).from_id(1).build().unwrap();
3006
3007            let resp_json: Value = serde_json::from_str(r#"[{"id":28457,"price":"4.00000100","qty":"12.00000000","quoteQty":"48.000012","time":1499865549590,"isBuyerMaker":true,"isBestMatch":true}]"#).unwrap();
3008            let expected_response : Vec<models::HistoricalTradesResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::HistoricalTradesResponseInner>");
3009
3010            let resp = client.historical_trades(params).await.expect("Expected a response");
3011            let data_future = resp.data();
3012            let actual_response = data_future.await.unwrap();
3013            assert_eq!(actual_response, expected_response);
3014        });
3015    }
3016
3017    #[test]
3018    fn historical_trades_response_error() {
3019        TOKIO_SHARED_RT.block_on(async {
3020            let client = MockMarketApiClient { force_error: true };
3021
3022            let params = HistoricalTradesParams::builder("BNBUSDT".to_string())
3023                .build()
3024                .unwrap();
3025
3026            match client.historical_trades(params).await {
3027                Ok(_) => panic!("Expected an error"),
3028                Err(err) => {
3029                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
3030                }
3031            }
3032        });
3033    }
3034
3035    #[test]
3036    fn klines_required_params_success() {
3037        TOKIO_SHARED_RT.block_on(async {
3038            let client = MockMarketApiClient { force_error: false };
3039
3040            let params = KlinesParams::builder("BNBUSDT".to_string(),KlinesIntervalEnum::Interval1s,).build().unwrap();
3041
3042            let resp_json: Value = serde_json::from_str(r#"[[1499040000000,"0.01634790","0.80000000","0.01575800","0.01577100","148976.11427815",1499644799999,"2434.19055334",308,"1756.87402397","28.46694368","0"]]"#).unwrap();
3043            let expected_response : Vec<Vec<models::KlinesItemInner>> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<Vec<models::KlinesItemInner>>");
3044
3045            let resp = client.klines(params).await.expect("Expected a response");
3046            let data_future = resp.data();
3047            let actual_response = data_future.await.unwrap();
3048            assert_eq!(actual_response, expected_response);
3049        });
3050    }
3051
3052    #[test]
3053    fn klines_optional_params_success() {
3054        TOKIO_SHARED_RT.block_on(async {
3055            let client = MockMarketApiClient { force_error: false };
3056
3057            let params = KlinesParams::builder("BNBUSDT".to_string(),KlinesIntervalEnum::Interval1s,).start_time(1735693200000).end_time(1735693200000).time_zone("time_zone_example".to_string()).limit(500).build().unwrap();
3058
3059            let resp_json: Value = serde_json::from_str(r#"[[1499040000000,"0.01634790","0.80000000","0.01575800","0.01577100","148976.11427815",1499644799999,"2434.19055334",308,"1756.87402397","28.46694368","0"]]"#).unwrap();
3060            let expected_response : Vec<Vec<models::KlinesItemInner>> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<Vec<models::KlinesItemInner>>");
3061
3062            let resp = client.klines(params).await.expect("Expected a response");
3063            let data_future = resp.data();
3064            let actual_response = data_future.await.unwrap();
3065            assert_eq!(actual_response, expected_response);
3066        });
3067    }
3068
3069    #[test]
3070    fn klines_response_error() {
3071        TOKIO_SHARED_RT.block_on(async {
3072            let client = MockMarketApiClient { force_error: true };
3073
3074            let params =
3075                KlinesParams::builder("BNBUSDT".to_string(), KlinesIntervalEnum::Interval1s)
3076                    .build()
3077                    .unwrap();
3078
3079            match client.klines(params).await {
3080                Ok(_) => panic!("Expected an error"),
3081                Err(err) => {
3082                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
3083                }
3084            }
3085        });
3086    }
3087
3088    #[test]
3089    fn reference_price_required_params_success() {
3090        TOKIO_SHARED_RT.block_on(async {
3091            let client = MockMarketApiClient { force_error: false };
3092
3093            let params = ReferencePriceParams::builder("BNBUSDT".to_string())
3094                .build()
3095                .unwrap();
3096
3097            let resp_json: Value = serde_json::from_str(
3098                r#"{"symbol":"BAZUSD","referencePrice":"10.00","timestamp":1770736694138}"#,
3099            )
3100            .unwrap();
3101            let expected_response: models::ReferencePriceResponse =
3102                serde_json::from_value(resp_json.clone())
3103                    .expect("should parse into models::ReferencePriceResponse");
3104
3105            let resp = client
3106                .reference_price(params)
3107                .await
3108                .expect("Expected a response");
3109            let data_future = resp.data();
3110            let actual_response = data_future.await.unwrap();
3111            assert_eq!(actual_response, expected_response);
3112        });
3113    }
3114
3115    #[test]
3116    fn reference_price_optional_params_success() {
3117        TOKIO_SHARED_RT.block_on(async {
3118            let client = MockMarketApiClient { force_error: false };
3119
3120            let params = ReferencePriceParams::builder("BNBUSDT".to_string())
3121                .build()
3122                .unwrap();
3123
3124            let resp_json: Value = serde_json::from_str(
3125                r#"{"symbol":"BAZUSD","referencePrice":"10.00","timestamp":1770736694138}"#,
3126            )
3127            .unwrap();
3128            let expected_response: models::ReferencePriceResponse =
3129                serde_json::from_value(resp_json.clone())
3130                    .expect("should parse into models::ReferencePriceResponse");
3131
3132            let resp = client
3133                .reference_price(params)
3134                .await
3135                .expect("Expected a response");
3136            let data_future = resp.data();
3137            let actual_response = data_future.await.unwrap();
3138            assert_eq!(actual_response, expected_response);
3139        });
3140    }
3141
3142    #[test]
3143    fn reference_price_response_error() {
3144        TOKIO_SHARED_RT.block_on(async {
3145            let client = MockMarketApiClient { force_error: true };
3146
3147            let params = ReferencePriceParams::builder("BNBUSDT".to_string())
3148                .build()
3149                .unwrap();
3150
3151            match client.reference_price(params).await {
3152                Ok(_) => panic!("Expected an error"),
3153                Err(err) => {
3154                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
3155                }
3156            }
3157        });
3158    }
3159
3160    #[test]
3161    fn reference_price_calculation_required_params_success() {
3162        TOKIO_SHARED_RT.block_on(async {
3163            let client = MockMarketApiClient { force_error: false };
3164
3165            let params = ReferencePriceCalculationParams::builder("BNBUSDT".to_string(),).build().unwrap();
3166
3167            let resp_json: Value = serde_json::from_str(r#"{"symbol":"BAZUSD","calculationType":"EXTERNAL","bucketCount":10,"bucketWidthMs":1000,"externalCalculationId":42}"#).unwrap();
3168            let expected_response : models::ReferencePriceCalculationResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::ReferencePriceCalculationResponse");
3169
3170            let resp = client.reference_price_calculation(params).await.expect("Expected a response");
3171            let data_future = resp.data();
3172            let actual_response = data_future.await.unwrap();
3173            assert_eq!(actual_response, expected_response);
3174        });
3175    }
3176
3177    #[test]
3178    fn reference_price_calculation_optional_params_success() {
3179        TOKIO_SHARED_RT.block_on(async {
3180            let client = MockMarketApiClient { force_error: false };
3181
3182            let params = ReferencePriceCalculationParams::builder("BNBUSDT".to_string(),).symbol_status(ReferencePriceCalculationSymbolStatusEnum::Trading).build().unwrap();
3183
3184            let resp_json: Value = serde_json::from_str(r#"{"symbol":"BAZUSD","calculationType":"EXTERNAL","bucketCount":10,"bucketWidthMs":1000,"externalCalculationId":42}"#).unwrap();
3185            let expected_response : models::ReferencePriceCalculationResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::ReferencePriceCalculationResponse");
3186
3187            let resp = client.reference_price_calculation(params).await.expect("Expected a response");
3188            let data_future = resp.data();
3189            let actual_response = data_future.await.unwrap();
3190            assert_eq!(actual_response, expected_response);
3191        });
3192    }
3193
3194    #[test]
3195    fn reference_price_calculation_response_error() {
3196        TOKIO_SHARED_RT.block_on(async {
3197            let client = MockMarketApiClient { force_error: true };
3198
3199            let params = ReferencePriceCalculationParams::builder("BNBUSDT".to_string())
3200                .build()
3201                .unwrap();
3202
3203            match client.reference_price_calculation(params).await {
3204                Ok(_) => panic!("Expected an error"),
3205                Err(err) => {
3206                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
3207                }
3208            }
3209        });
3210    }
3211
3212    #[test]
3213    fn ticker_required_params_success() {
3214        TOKIO_SHARED_RT.block_on(async {
3215            let client = MockMarketApiClient { force_error: false };
3216
3217            let params = TickerParams::builder().build().unwrap();
3218
3219            let resp_json: Value = serde_json::from_str(r#"{"symbol":"LTCBTC","priceChange":"-8.00000000","priceChangePercent":"-88.889","weightedAvgPrice":"2.60427807","openPrice":"0.10000000","highPrice":"2.00000000","lowPrice":"0.10000000","lastPrice":"2.00000000","volume":"39.00000000","quoteVolume":"13.40000000","openTime":1656986580000,"closeTime":1657001016795,"firstId":0,"lastId":34,"count":35}"#).unwrap();
3220            let expected_response : models::TickerResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::TickerResponse");
3221
3222            let resp = client.ticker(params).await.expect("Expected a response");
3223            let data_future = resp.data();
3224            let actual_response = data_future.await.unwrap();
3225            assert_eq!(actual_response, expected_response);
3226        });
3227    }
3228
3229    #[test]
3230    fn ticker_optional_params_success() {
3231        TOKIO_SHARED_RT.block_on(async {
3232            let client = MockMarketApiClient { force_error: false };
3233
3234            let params = TickerParams::builder().symbol("BNBUSDT".to_string()).symbols(["null".to_string(),].to_vec()).window_size(TickerWindowSizeEnum::WindowSize1m).r#type(TickerTypeEnum::Full).symbol_status(TickerSymbolStatusEnum::Trading).build().unwrap();
3235
3236            let resp_json: Value = serde_json::from_str(r#"{"symbol":"LTCBTC","priceChange":"-8.00000000","priceChangePercent":"-88.889","weightedAvgPrice":"2.60427807","openPrice":"0.10000000","highPrice":"2.00000000","lowPrice":"0.10000000","lastPrice":"2.00000000","volume":"39.00000000","quoteVolume":"13.40000000","openTime":1656986580000,"closeTime":1657001016795,"firstId":0,"lastId":34,"count":35}"#).unwrap();
3237            let expected_response : models::TickerResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::TickerResponse");
3238
3239            let resp = client.ticker(params).await.expect("Expected a response");
3240            let data_future = resp.data();
3241            let actual_response = data_future.await.unwrap();
3242            assert_eq!(actual_response, expected_response);
3243        });
3244    }
3245
3246    #[test]
3247    fn ticker_response_error() {
3248        TOKIO_SHARED_RT.block_on(async {
3249            let client = MockMarketApiClient { force_error: true };
3250
3251            let params = TickerParams::builder().build().unwrap();
3252
3253            match client.ticker(params).await {
3254                Ok(_) => panic!("Expected an error"),
3255                Err(err) => {
3256                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
3257                }
3258            }
3259        });
3260    }
3261
3262    #[test]
3263    fn ticker24hr_required_params_success() {
3264        TOKIO_SHARED_RT.block_on(async {
3265            let client = MockMarketApiClient { force_error: false };
3266
3267            let params = Ticker24hrParams::builder().build().unwrap();
3268
3269            let resp_json: Value = serde_json::from_str(r#"{"symbol":"BNBBTC","priceChange":"-94.99999800","priceChangePercent":"-95.960","weightedAvgPrice":"0.29628482","prevClosePrice":"0.10002000","lastPrice":"4.00000200","lastQty":"200.00000000","bidPrice":"4.00000000","bidQty":"100.00000000","askPrice":"4.00000200","askQty":"100.00000000","openPrice":"99.00000000","highPrice":"100.00000000","lowPrice":"0.10000000","volume":"8913.30000000","quoteVolume":"15.30000000","openTime":1499783499040,"closeTime":1499869899040,"firstId":28385,"lastId":28460,"count":76}"#).unwrap();
3270            let expected_response : models::Ticker24hrResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::Ticker24hrResponse");
3271
3272            let resp = client.ticker24hr(params).await.expect("Expected a response");
3273            let data_future = resp.data();
3274            let actual_response = data_future.await.unwrap();
3275            assert_eq!(actual_response, expected_response);
3276        });
3277    }
3278
3279    #[test]
3280    fn ticker24hr_optional_params_success() {
3281        TOKIO_SHARED_RT.block_on(async {
3282            let client = MockMarketApiClient { force_error: false };
3283
3284            let params = Ticker24hrParams::builder().symbol("BNBUSDT".to_string()).symbols(["null".to_string(),].to_vec()).r#type(Ticker24hrTypeEnum::Full).symbol_status(Ticker24hrSymbolStatusEnum::Trading).build().unwrap();
3285
3286            let resp_json: Value = serde_json::from_str(r#"{"symbol":"BNBBTC","priceChange":"-94.99999800","priceChangePercent":"-95.960","weightedAvgPrice":"0.29628482","prevClosePrice":"0.10002000","lastPrice":"4.00000200","lastQty":"200.00000000","bidPrice":"4.00000000","bidQty":"100.00000000","askPrice":"4.00000200","askQty":"100.00000000","openPrice":"99.00000000","highPrice":"100.00000000","lowPrice":"0.10000000","volume":"8913.30000000","quoteVolume":"15.30000000","openTime":1499783499040,"closeTime":1499869899040,"firstId":28385,"lastId":28460,"count":76}"#).unwrap();
3287            let expected_response : models::Ticker24hrResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::Ticker24hrResponse");
3288
3289            let resp = client.ticker24hr(params).await.expect("Expected a response");
3290            let data_future = resp.data();
3291            let actual_response = data_future.await.unwrap();
3292            assert_eq!(actual_response, expected_response);
3293        });
3294    }
3295
3296    #[test]
3297    fn ticker24hr_response_error() {
3298        TOKIO_SHARED_RT.block_on(async {
3299            let client = MockMarketApiClient { force_error: true };
3300
3301            let params = Ticker24hrParams::builder().build().unwrap();
3302
3303            match client.ticker24hr(params).await {
3304                Ok(_) => panic!("Expected an error"),
3305                Err(err) => {
3306                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
3307                }
3308            }
3309        });
3310    }
3311
3312    #[test]
3313    fn ticker_book_ticker_required_params_success() {
3314        TOKIO_SHARED_RT.block_on(async {
3315            let client = MockMarketApiClient { force_error: false };
3316
3317            let params = TickerBookTickerParams::builder().build().unwrap();
3318
3319            let resp_json: Value = serde_json::from_str(r#"{"symbol":"LTCBTC","bidPrice":"4.00000000","bidQty":"431.00000000","askPrice":"4.00000200","askQty":"9.00000000"}"#).unwrap();
3320            let expected_response : models::TickerBookTickerResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::TickerBookTickerResponse");
3321
3322            let resp = client.ticker_book_ticker(params).await.expect("Expected a response");
3323            let data_future = resp.data();
3324            let actual_response = data_future.await.unwrap();
3325            assert_eq!(actual_response, expected_response);
3326        });
3327    }
3328
3329    #[test]
3330    fn ticker_book_ticker_optional_params_success() {
3331        TOKIO_SHARED_RT.block_on(async {
3332            let client = MockMarketApiClient { force_error: false };
3333
3334            let params = TickerBookTickerParams::builder().symbol("BNBUSDT".to_string()).symbols(["null".to_string(),].to_vec()).symbol_status(TickerBookTickerSymbolStatusEnum::Trading).build().unwrap();
3335
3336            let resp_json: Value = serde_json::from_str(r#"{"symbol":"LTCBTC","bidPrice":"4.00000000","bidQty":"431.00000000","askPrice":"4.00000200","askQty":"9.00000000"}"#).unwrap();
3337            let expected_response : models::TickerBookTickerResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::TickerBookTickerResponse");
3338
3339            let resp = client.ticker_book_ticker(params).await.expect("Expected a response");
3340            let data_future = resp.data();
3341            let actual_response = data_future.await.unwrap();
3342            assert_eq!(actual_response, expected_response);
3343        });
3344    }
3345
3346    #[test]
3347    fn ticker_book_ticker_response_error() {
3348        TOKIO_SHARED_RT.block_on(async {
3349            let client = MockMarketApiClient { force_error: true };
3350
3351            let params = TickerBookTickerParams::builder().build().unwrap();
3352
3353            match client.ticker_book_ticker(params).await {
3354                Ok(_) => panic!("Expected an error"),
3355                Err(err) => {
3356                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
3357                }
3358            }
3359        });
3360    }
3361
3362    #[test]
3363    fn ticker_price_required_params_success() {
3364        TOKIO_SHARED_RT.block_on(async {
3365            let client = MockMarketApiClient { force_error: false };
3366
3367            let params = TickerPriceParams::builder().build().unwrap();
3368
3369            let resp_json: Value =
3370                serde_json::from_str(r#"{"symbol":"LTCBTC","price":"4.00000200"}"#).unwrap();
3371            let expected_response: models::TickerPriceResponse =
3372                serde_json::from_value(resp_json.clone())
3373                    .expect("should parse into models::TickerPriceResponse");
3374
3375            let resp = client
3376                .ticker_price(params)
3377                .await
3378                .expect("Expected a response");
3379            let data_future = resp.data();
3380            let actual_response = data_future.await.unwrap();
3381            assert_eq!(actual_response, expected_response);
3382        });
3383    }
3384
3385    #[test]
3386    fn ticker_price_optional_params_success() {
3387        TOKIO_SHARED_RT.block_on(async {
3388            let client = MockMarketApiClient { force_error: false };
3389
3390            let params = TickerPriceParams::builder()
3391                .symbol("BNBUSDT".to_string())
3392                .symbols(["null".to_string()].to_vec())
3393                .symbol_status(TickerPriceSymbolStatusEnum::Trading)
3394                .build()
3395                .unwrap();
3396
3397            let resp_json: Value =
3398                serde_json::from_str(r#"{"symbol":"LTCBTC","price":"4.00000200"}"#).unwrap();
3399            let expected_response: models::TickerPriceResponse =
3400                serde_json::from_value(resp_json.clone())
3401                    .expect("should parse into models::TickerPriceResponse");
3402
3403            let resp = client
3404                .ticker_price(params)
3405                .await
3406                .expect("Expected a response");
3407            let data_future = resp.data();
3408            let actual_response = data_future.await.unwrap();
3409            assert_eq!(actual_response, expected_response);
3410        });
3411    }
3412
3413    #[test]
3414    fn ticker_price_response_error() {
3415        TOKIO_SHARED_RT.block_on(async {
3416            let client = MockMarketApiClient { force_error: true };
3417
3418            let params = TickerPriceParams::builder().build().unwrap();
3419
3420            match client.ticker_price(params).await {
3421                Ok(_) => panic!("Expected an error"),
3422                Err(err) => {
3423                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
3424                }
3425            }
3426        });
3427    }
3428
3429    #[test]
3430    fn ticker_trading_day_required_params_success() {
3431        TOKIO_SHARED_RT.block_on(async {
3432            let client = MockMarketApiClient { force_error: false };
3433
3434            let params = TickerTradingDayParams::builder().build().unwrap();
3435
3436            let resp_json: Value = serde_json::from_str(r#"{"symbol":"BTCUSDT","priceChange":"-83.13000000","priceChangePercent":"-0.317","weightedAvgPrice":"26234.58803036","openPrice":"26304.80000000","highPrice":"26397.46000000","lowPrice":"26088.34000000","lastPrice":"26221.67000000","volume":"18495.35066000","quoteVolume":"485217905.04210480","openTime":1695686400000,"closeTime":1695772799999,"firstId":3220151555,"lastId":3220849281,"count":697727}"#).unwrap();
3437            let expected_response : models::TickerTradingDayResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::TickerTradingDayResponse");
3438
3439            let resp = client.ticker_trading_day(params).await.expect("Expected a response");
3440            let data_future = resp.data();
3441            let actual_response = data_future.await.unwrap();
3442            assert_eq!(actual_response, expected_response);
3443        });
3444    }
3445
3446    #[test]
3447    fn ticker_trading_day_optional_params_success() {
3448        TOKIO_SHARED_RT.block_on(async {
3449            let client = MockMarketApiClient { force_error: false };
3450
3451            let params = TickerTradingDayParams::builder().symbol("BNBUSDT".to_string()).symbols(["null".to_string(),].to_vec()).time_zone("time_zone_example".to_string()).r#type(TickerTradingDayTypeEnum::Full).symbol_status(TickerTradingDaySymbolStatusEnum::Trading).build().unwrap();
3452
3453            let resp_json: Value = serde_json::from_str(r#"{"symbol":"BTCUSDT","priceChange":"-83.13000000","priceChangePercent":"-0.317","weightedAvgPrice":"26234.58803036","openPrice":"26304.80000000","highPrice":"26397.46000000","lowPrice":"26088.34000000","lastPrice":"26221.67000000","volume":"18495.35066000","quoteVolume":"485217905.04210480","openTime":1695686400000,"closeTime":1695772799999,"firstId":3220151555,"lastId":3220849281,"count":697727}"#).unwrap();
3454            let expected_response : models::TickerTradingDayResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::TickerTradingDayResponse");
3455
3456            let resp = client.ticker_trading_day(params).await.expect("Expected a response");
3457            let data_future = resp.data();
3458            let actual_response = data_future.await.unwrap();
3459            assert_eq!(actual_response, expected_response);
3460        });
3461    }
3462
3463    #[test]
3464    fn ticker_trading_day_response_error() {
3465        TOKIO_SHARED_RT.block_on(async {
3466            let client = MockMarketApiClient { force_error: true };
3467
3468            let params = TickerTradingDayParams::builder().build().unwrap();
3469
3470            match client.ticker_trading_day(params).await {
3471                Ok(_) => panic!("Expected an error"),
3472                Err(err) => {
3473                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
3474                }
3475            }
3476        });
3477    }
3478
3479    #[test]
3480    fn ui_klines_required_params_success() {
3481        TOKIO_SHARED_RT.block_on(async {
3482            let client = MockMarketApiClient { force_error: false };
3483
3484            let params = UiKlinesParams::builder("BNBUSDT".to_string(),UiKlinesIntervalEnum::Interval1s,).build().unwrap();
3485
3486            let resp_json: Value = serde_json::from_str(r#"[[1499040000000,"0.01634790","0.80000000","0.01575800","0.01577100","148976.11427815",1499644799999,"2434.19055334",308,"1756.87402397","28.46694368","0"]]"#).unwrap();
3487            let expected_response : Vec<Vec<models::KlinesItemInner>> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<Vec<models::KlinesItemInner>>");
3488
3489            let resp = client.ui_klines(params).await.expect("Expected a response");
3490            let data_future = resp.data();
3491            let actual_response = data_future.await.unwrap();
3492            assert_eq!(actual_response, expected_response);
3493        });
3494    }
3495
3496    #[test]
3497    fn ui_klines_optional_params_success() {
3498        TOKIO_SHARED_RT.block_on(async {
3499            let client = MockMarketApiClient { force_error: false };
3500
3501            let params = UiKlinesParams::builder("BNBUSDT".to_string(),UiKlinesIntervalEnum::Interval1s,).start_time(1735693200000).end_time(1735693200000).time_zone("time_zone_example".to_string()).limit(500).build().unwrap();
3502
3503            let resp_json: Value = serde_json::from_str(r#"[[1499040000000,"0.01634790","0.80000000","0.01575800","0.01577100","148976.11427815",1499644799999,"2434.19055334",308,"1756.87402397","28.46694368","0"]]"#).unwrap();
3504            let expected_response : Vec<Vec<models::KlinesItemInner>> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<Vec<models::KlinesItemInner>>");
3505
3506            let resp = client.ui_klines(params).await.expect("Expected a response");
3507            let data_future = resp.data();
3508            let actual_response = data_future.await.unwrap();
3509            assert_eq!(actual_response, expected_response);
3510        });
3511    }
3512
3513    #[test]
3514    fn ui_klines_response_error() {
3515        TOKIO_SHARED_RT.block_on(async {
3516            let client = MockMarketApiClient { force_error: true };
3517
3518            let params =
3519                UiKlinesParams::builder("BNBUSDT".to_string(), UiKlinesIntervalEnum::Interval1s)
3520                    .build()
3521                    .unwrap();
3522
3523            match client.ui_klines(params).await {
3524                Ok(_) => panic!("Expected an error"),
3525                Err(err) => {
3526                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
3527                }
3528            }
3529        });
3530    }
3531}