binance/
rest_model.rs

1use chrono::{DateTime, Utc};
2use serde_repr::{Deserialize_repr, Serialize_repr};
3use std::collections::HashMap;
4
5#[derive(Debug, Serialize, Deserialize, Clone)]
6#[serde(rename_all = "camelCase")]
7pub struct ServerTime {
8    pub server_time: u64,
9}
10
11#[derive(Debug, Serialize, Deserialize, Clone)]
12#[serde(rename_all = "camelCase")]
13pub struct ExchangeInformation {
14    pub timezone: String,
15    pub server_time: u64,
16    pub rate_limits: Vec<RateLimit>,
17    pub symbols: Vec<Symbol>,
18    pub exchange_filters: Vec<Filters>,
19}
20
21#[derive(Debug, Serialize, Deserialize, Clone)]
22#[serde(rename_all = "camelCase")]
23pub struct Symbol {
24    pub symbol: String,
25    pub status: String,
26    pub base_asset: String,
27    pub base_asset_precision: u64,
28    pub quote_asset: String,
29    pub quote_precision: u64,
30    pub quote_asset_precision: u64,
31    pub base_commission_precision: u64,
32    pub quote_commission_precision: u64,
33    pub order_types: Vec<OrderType>,
34    pub iceberg_allowed: bool,
35    pub oco_allowed: bool,
36    pub quote_order_qty_market_allowed: bool,
37    pub is_spot_trading_allowed: bool,
38    pub is_margin_trading_allowed: bool,
39    pub filters: Vec<Filters>,
40    pub permissions: Vec<SymbolPermission>,
41}
42
43impl Symbol {
44    pub fn lot_size(&self) -> Option<Filters> {
45        self.filters
46            .iter()
47            .find(|filter| matches!(filter, Filters::LotSize { .. }))
48            .cloned()
49    }
50
51    pub fn market_lot_size(&self) -> Option<Filters> {
52        self.filters
53            .iter()
54            .find(|filter| matches!(filter, Filters::MarketLotSize { .. }))
55            .cloned()
56    }
57}
58
59#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
60#[serde(tag = "filterType")]
61pub enum Filters {
62    #[serde(rename = "PRICE_FILTER")]
63    #[serde(rename_all = "camelCase")]
64    PriceFilter {
65        #[serde(with = "string_or_float")]
66        min_price: f64,
67        #[serde(with = "string_or_float")]
68        max_price: f64,
69        #[serde(with = "string_or_float")]
70        tick_size: f64,
71    },
72    #[serde(rename = "PERCENT_PRICE")]
73    #[serde(rename_all = "camelCase")]
74    PercentPrice {
75        #[serde(with = "string_or_float")]
76        multiplier_up: f64,
77        #[serde(with = "string_or_float")]
78        multiplier_down: f64,
79        avg_price_mins: u64,
80    },
81    #[serde(rename = "LOT_SIZE")]
82    #[serde(rename_all = "camelCase")]
83    LotSize {
84        #[serde(with = "string_or_float")]
85        min_qty: f64,
86        #[serde(with = "string_or_float")]
87        max_qty: f64,
88        #[serde(with = "string_or_float")]
89        step_size: f64,
90    },
91    #[serde(rename = "MARKET_LOT_SIZE")]
92    #[serde(rename_all = "camelCase")]
93    MarketLotSize {
94        #[serde(with = "string_or_float")]
95        min_qty: f64,
96        #[serde(with = "string_or_float")]
97        max_qty: f64,
98        #[serde(with = "string_or_float")]
99        step_size: f64,
100    },
101    #[serde(rename = "MIN_NOTIONAL")]
102    #[serde(rename_all = "camelCase")]
103    MinNotional {
104        #[serde(with = "string_or_float")]
105        min_notional: f64,
106        apply_to_market: bool,
107        avg_price_mins: u64,
108    },
109    #[serde(rename = "ICEBERG_PARTS")]
110    #[serde(rename_all = "camelCase")]
111    IcebergParts { limit: u16 },
112    #[serde(rename = "MAX_NUM_ORDERS")]
113    #[serde(rename_all = "camelCase")]
114    MaxNumOrders { max_num_orders: u16 },
115    #[serde(rename = "MAX_NUM_ALGO_ORDERS")]
116    #[serde(rename_all = "camelCase")]
117    MaxNumAlgoOrders { max_num_algo_orders: u16 },
118    #[serde(rename = "MAX_NUM_ICEBERG_ORDERS")]
119    #[serde(rename_all = "camelCase")]
120    MaxNumIcebergOrders { max_num_iceberg_orders: u16 },
121    #[serde(rename = "MAX_POSITION")]
122    #[serde(rename_all = "camelCase")]
123    MaxPosition {
124        #[serde(with = "string_or_float")]
125        max_position: f64,
126    },
127    #[serde(rename = "EXCHANGE_MAX_NUM_ORDERS")]
128    #[serde(rename_all = "camelCase")]
129    ExchangeMaxNumOrders { max_num_orders: u16 },
130    #[serde(rename = "EXCHANGE_MAX_ALGO_ORDERS")]
131    #[serde(rename_all = "camelCase")]
132    ExchangeMaxNumAlgoOrders { max_num_algo_orders: u16 },
133    #[serde(other)]
134    Others,
135}
136
137#[derive(Debug, Serialize, Deserialize, Clone)]
138#[serde(rename_all = "camelCase")]
139pub struct AccountInformation {
140    pub maker_commission: f32,
141    pub taker_commission: f32,
142    pub buyer_commission: f32,
143    pub seller_commission: f32,
144    pub can_trade: bool,
145    pub can_withdraw: bool,
146    pub can_deposit: bool,
147    pub account_type: AccountType,
148    pub balances: Vec<Balance>,
149    pub permissions: Vec<AccountType>,
150    pub update_time: i64,
151}
152
153#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
154#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
155pub enum MarketPermission {
156    Spot,
157    Margin,
158    #[serde(other)]
159    Other,
160}
161
162#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
163#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
164pub enum AccountType {
165    Spot,
166    UsdtFuture,
167    CoinFuture,
168    Leveraged,
169    #[serde(other)]
170    Other,
171}
172
173#[derive(Debug, Serialize, Deserialize, Clone)]
174#[serde(rename_all = "camelCase")]
175pub struct Balance {
176    pub asset: String,
177    #[serde(with = "string_or_float")]
178    pub free: f64,
179    #[serde(with = "string_or_float")]
180    pub locked: f64,
181}
182
183#[derive(Debug, Serialize, Deserialize, Clone)]
184#[serde(rename_all = "camelCase")]
185pub struct Order {
186    pub symbol: String,
187    pub order_id: u64,
188    pub order_list_id: i32,
189    pub client_order_id: String,
190    #[serde(with = "string_or_float")]
191    pub price: f64,
192    #[serde(with = "string_or_float")]
193    pub orig_qty: f64,
194    #[serde(with = "string_or_float")]
195    pub executed_qty: f64,
196    #[serde(with = "string_or_float")]
197    pub cummulative_quote_qty: f64,
198    pub status: OrderStatus,
199    pub time_in_force: TimeInForce,
200    #[serde(rename = "type")]
201    pub order_type: OrderType,
202    pub side: OrderSide,
203    #[serde(with = "string_or_float")]
204    pub stop_price: f64,
205    #[serde(with = "string_or_float")]
206    pub iceberg_qty: f64,
207    pub time: u64,
208    pub update_time: u64,
209    pub is_working: bool,
210    #[serde(with = "string_or_float")]
211    pub orig_quote_order_qty: f64,
212}
213
214#[derive(Debug, Serialize, Deserialize, Clone)]
215#[serde(rename_all = "camelCase")]
216pub struct OrderCanceled {
217    pub symbol: String,
218    pub orig_client_order_id: String,
219    pub order_id: u64,
220    pub client_order_id: String,
221}
222
223#[derive(Debug, Serialize, Deserialize, Clone)]
224#[serde(rename_all = "camelCase")]
225pub struct OrderCanceledReplaced {
226    pub cancel_result: String,
227    pub new_order_result: String,
228    pub cancel_response: OrderCanceled,
229    pub new_order_response: Transaction,
230}
231
232#[derive(Debug, Serialize, Deserialize, Clone)]
233#[serde(rename_all = "camelCase")]
234pub struct Fill {
235    #[serde(with = "string_or_float")]
236    pub price: f64,
237    #[serde(with = "string_or_float")]
238    pub qty: f64,
239    #[serde(with = "string_or_float")]
240    pub commission: f64,
241    pub commission_asset: String,
242}
243
244#[derive(Debug, Serialize, Deserialize, Clone)]
245#[serde(rename_all = "camelCase")]
246pub struct Transaction {
247    pub symbol: String,
248    pub order_id: u64,
249    pub client_order_id: String,
250    pub transact_time: u64,
251    #[serde(with = "string_or_float")]
252    pub price: f64,
253    #[serde(with = "string_or_float")]
254    pub orig_qty: f64,
255    #[serde(with = "string_or_float")]
256    pub executed_qty: f64,
257    #[serde(with = "string_or_float")]
258    pub cummulative_quote_qty: f64,
259    pub status: OrderStatus,
260    pub time_in_force: TimeInForce,
261    #[serde(rename = "type")]
262    pub order_type: OrderType,
263    pub side: OrderSide,
264    pub fills: Vec<Fill>,
265}
266
267#[derive(Debug, Serialize, Deserialize, Clone)]
268#[serde(rename_all = "camelCase")]
269pub struct TransactionId {
270    pub tran_id: u64,
271}
272
273/// Response to a test order (endpoint /api/v3/order/test).
274///
275/// Currently, the API responds {} on a successfull test transaction,
276/// hence this struct has no fields.
277#[derive(Debug, Serialize, Deserialize, Clone)]
278#[serde(rename_all = "camelCase")]
279pub struct TestResponse {}
280
281#[derive(Debug, Serialize, Deserialize, Clone)]
282#[serde(rename_all = "camelCase")]
283pub struct OrderBook {
284    pub last_update_id: u64,
285    pub bids: Vec<Bids>,
286    pub asks: Vec<Asks>,
287}
288
289#[derive(Debug, Serialize, Deserialize, Clone)]
290pub struct Bids {
291    #[serde(with = "string_or_float")]
292    pub price: f64,
293    #[serde(with = "string_or_float")]
294    pub qty: f64,
295}
296
297#[derive(Debug, Serialize, Deserialize, Clone)]
298pub struct Asks {
299    #[serde(with = "string_or_float")]
300    pub price: f64,
301    #[serde(with = "string_or_float")]
302    pub qty: f64,
303}
304
305#[derive(Debug, Serialize, Deserialize, Clone)]
306#[serde(rename_all = "camelCase")]
307pub struct UserDataStream {
308    pub listen_key: String,
309}
310
311#[derive(Debug, Serialize, Deserialize, Clone)]
312pub struct Success {}
313
314#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
315#[serde(rename_all = "camelCase")]
316#[serde(untagged)]
317pub enum Prices {
318    AllPrices(Vec<SymbolPrice>),
319}
320
321#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
322pub struct SymbolPrice {
323    pub symbol: String,
324    #[serde(with = "string_or_float")]
325    pub price: f64,
326}
327
328#[derive(Debug, Serialize, Deserialize, Clone)]
329pub struct AveragePrice {
330    pub mins: u64,
331    #[serde(with = "string_or_float")]
332    pub price: f64,
333}
334
335#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
336#[serde(rename_all = "camelCase")]
337#[serde(untagged)]
338pub enum BookTickers {
339    AllBookTickers(Vec<Tickers>),
340}
341
342#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
343pub enum KlineSummaries {
344    AllKlineSummaries(Vec<KlineSummary>),
345}
346
347#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
348#[serde(rename_all = "camelCase")]
349pub struct Tickers {
350    pub symbol: String,
351    #[serde(with = "string_or_float")]
352    pub bid_price: f64,
353    #[serde(with = "string_or_float")]
354    pub bid_qty: f64,
355    #[serde(with = "string_or_float")]
356    pub ask_price: f64,
357    #[serde(with = "string_or_float")]
358    pub ask_qty: f64,
359}
360
361#[derive(Debug, Serialize, Deserialize, Clone)]
362#[serde(rename_all = "camelCase")]
363pub struct TradeHistory {
364    pub id: u64,
365    #[serde(with = "string_or_float")]
366    pub price: f64,
367    #[serde(with = "string_or_float")]
368    pub qty: f64,
369    pub commission: String,
370    pub commission_asset: String,
371    pub time: u64,
372    pub is_buyer: bool,
373    pub is_maker: bool,
374    pub is_best_match: bool,
375}
376
377#[derive(Debug, Serialize, Deserialize, Clone)]
378#[serde(rename_all = "camelCase")]
379pub struct PriceStats {
380    pub price_change: String,
381    pub price_change_percent: String,
382    pub weighted_avg_price: String,
383    #[serde(with = "string_or_float")]
384    pub prev_close_price: f64,
385    #[serde(with = "string_or_float")]
386    pub last_price: f64,
387    #[serde(with = "string_or_float")]
388    pub bid_price: f64,
389    #[serde(with = "string_or_float")]
390    pub ask_price: f64,
391    #[serde(with = "string_or_float")]
392    pub open_price: f64,
393    #[serde(with = "string_or_float")]
394    pub high_price: f64,
395    #[serde(with = "string_or_float")]
396    pub low_price: f64,
397    #[serde(with = "string_or_float")]
398    pub volume: f64,
399    pub open_time: u64,
400    pub close_time: u64,
401    pub first_id: u64,
402    pub last_id: u64,
403    pub count: u64,
404}
405
406#[derive(Debug, Serialize, Deserialize, Clone)]
407pub struct AggTrade {
408    #[serde(rename = "T")]
409    pub time: u64,
410    #[serde(rename = "a")]
411    pub agg_id: u64,
412    #[serde(rename = "f")]
413    pub first_id: u64,
414    #[serde(rename = "l")]
415    pub last_id: u64,
416    #[serde(rename = "m")]
417    pub maker: bool,
418    #[serde(rename = "M")]
419    pub best_match: bool,
420    #[serde(rename = "p", with = "string_or_float")]
421    pub price: f64,
422    #[serde(rename = "q", with = "string_or_float")]
423    pub qty: f64,
424}
425
426#[derive(Debug, Serialize_repr, Deserialize_repr, Clone, PartialEq, Eq)]
427#[repr(u8)]
428pub enum MarginTransferType {
429    FromMainToMargin = 1,
430    FromMarginToMain = 2,
431}
432
433#[derive(Debug, Serialize, Deserialize, Clone)]
434#[serde(rename_all = "camelCase")]
435pub struct Transfer {
436    pub asset: String,
437    pub amount: f64,
438    #[serde(rename(serialize = "type", deserialize = "type"))]
439    pub transfer_type: MarginTransferType,
440}
441
442#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
443#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
444pub enum IsolatedMarginTransferType {
445    Spot,
446    IsolatedMargin,
447}
448
449#[derive(Debug, Serialize, Deserialize, Clone)]
450#[serde(rename_all = "camelCase")]
451pub struct IsolatedTransfer {
452    pub asset: String,
453    pub symbol: String,
454    pub amount: f64,
455    pub trans_from: IsolatedMarginTransferType,
456    pub trans_to: IsolatedMarginTransferType,
457}
458
459#[derive(Debug, Serialize, Deserialize, Clone)]
460#[serde(rename_all = "camelCase")]
461pub struct Loan {
462    pub asset: String,
463    pub amount: f64,
464    pub is_isolated: Option<String>,
465    pub symbol: Option<String>,
466}
467
468/// How long will an order stay alive
469#[derive(Eq, PartialEq, Debug, Serialize, Deserialize, Clone)]
470pub enum TimeInForce {
471    /// Good Till Canceled
472    GTC,
473    /// Immediate Or Cancel
474    IOC,
475    /// Fill or Kill
476    FOK,
477    /// Good till expired
478    GTX,
479    #[serde(other)]
480    Other,
481}
482
483#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
484#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
485pub enum OrderResponse {
486    Ack,
487    Result,
488    Full,
489    #[serde(other)]
490    Other,
491}
492
493#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
494#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
495pub enum SideEffectType {
496    NoSideEffect,
497    MarginBuy,
498    AutoRepay,
499    #[serde(other)]
500    Other,
501}
502
503#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
504#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
505pub enum OrderSide {
506    Buy,
507    Sell,
508}
509
510/// By default, buy
511impl Default for OrderSide {
512    fn default() -> Self { Self::Buy }
513}
514
515/// The allowed values are:
516/// STOP_ON_FAILURE - If the cancel request fails, the new order placement will not be attempted.
517/// ALLOW_FAILURE - new order placement will be attempted even if cancel request fails.
518#[derive(Debug, Serialize, Deserialize, Clone)]
519#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
520pub enum CancelReplaceMode {
521    StopOnFailure,
522    AllowFailure,
523}
524
525/// By default, STOP_ON_FAILURE
526impl Default for CancelReplaceMode {
527    fn default() -> Self { Self::StopOnFailure }
528}
529
530/// Order types, the following restrictions apply
531/// LIMIT_MAKER are LIMIT orders that will be rejected if they would immediately match and trade as a taker.
532/// STOP_LOSS and TAKE_PROFIT will execute a MARKET order when the stopPrice is reached.
533/// Any LIMIT or LIMIT_MAKER type order can be made an iceberg order by sending an icebergQty.
534/// Any order with an icebergQty MUST have timeInForce set to GTC.
535/// MARKET orders using quantity specifies how much a user wants to buy or sell based on the market price.
536/// MARKET orders using quoteOrderQty specifies the amount the user wants to spend (when buying) or receive (when selling) of the quote asset; the correct quantity will be determined based on the market liquidity and quoteOrderQty.
537/// MARKET orders using quoteOrderQty will not break LOT_SIZE filter rules; the order will execute a quantity that will have the notional value as close as possible to quoteOrderQty.
538#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
539#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
540pub enum OrderType {
541    Limit,
542    Market,
543    StopLoss,
544    StopLossLimit,
545    TakeProfit,
546    TakeProfitLimit,
547    LimitMaker,
548    #[serde(other)]
549    Other,
550}
551
552/// By default, use market orders
553impl Default for OrderType {
554    fn default() -> Self { Self::Market }
555}
556
557#[derive(Debug, Serialize, Deserialize, Clone)]
558#[serde(rename_all = "camelCase")]
559pub struct MarginOrder {
560    pub symbol: String,
561    pub side: OrderSide,
562    #[serde(rename(serialize = "type", deserialize = "type"))]
563    pub order_type: OrderType,
564    pub quantity: Option<f64>,
565    pub quote_order_qty: Option<f64>,
566    pub price: Option<f64>,
567    /// Used with `OrderType::StopLoss`, `OrderType::StopLossLimit`, `OrderType::TakeProfit` and `OrderType::TakeProfitLimit`
568    pub stop_price: Option<f64>,
569    pub new_client_order_id: Option<String>,
570    /// Used with `OrderType::Limit`, `OrderType::StopLossLimit` and `OrderType::TakeProfitLimit` to create an iceberg order
571    pub iceberg_qty: Option<f64>,
572    /// Default is `OrderResponse::ACK`
573    pub new_order_resp_type: OrderResponse,
574    /// N.B. : do not set with `OrderType::Market`
575    pub time_in_force: Option<TimeInForce>,
576    /// "TRUE" or "FALSE", in upper case, default is "FALSE"
577    pub is_isolated: Option<String>,
578    /// Default is `SideEffectType::NoSideEffect`
579    pub side_effect_type: SideEffectType,
580}
581
582#[derive(Debug, Serialize, Deserialize, Clone)]
583#[serde(rename_all = "camelCase")]
584pub struct MarginOrderCancellation {
585    pub symbol: String,
586    pub order_id: u64,
587    pub orig_client_order_id: String,
588    pub new_client_order_id: String,
589    pub is_isolated: Option<String>,
590}
591
592#[derive(Debug, Serialize, Deserialize, Clone)]
593#[serde(rename_all = "camelCase")]
594pub struct MarginOrderCancellationResult {
595    pub symbol: String,
596    #[serde(with = "string_or_u64_opt")]
597    pub order_id: Option<u64>,
598    pub orig_client_order_id: Option<String>,
599    pub client_order_id: Option<String>,
600    #[serde(with = "string_or_float_opt")]
601    pub price: Option<f64>,
602    #[serde(with = "string_or_float_opt")]
603    pub orig_qty: Option<f64>,
604    #[serde(with = "string_or_float_opt")]
605    pub executed_qty: Option<f64>,
606    #[serde(with = "string_or_float_opt")]
607    pub cummulative_quote_qty: Option<f64>,
608    pub status: Option<OrderStatus>,
609    pub time_in_force: Option<TimeInForce>,
610    #[serde(rename(serialize = "type", deserialize = "type"))]
611    pub order_type: Option<OrderType>,
612    pub side: Option<OrderSide>,
613    pub is_isolated: Option<bool>,
614    pub order_list_id: Option<i64>,
615    pub transaction_time: Option<u64>,
616    pub contingency_type: Option<ContingencyType>,
617    pub orders: Option<Vec<OCOOrderDetail>>,
618    pub order_reports: Option<Vec<OCOOrderReport>>,
619}
620
621#[derive(Debug, Serialize, Deserialize, Clone)]
622#[serde(rename_all = "camelCase")]
623pub struct MarginOrdersCancellation {
624    pub symbol: String,
625    pub is_isolated: Option<String>,
626}
627
628pub type MarginOrdersCancellationResult = Vec<MarginOrderCancellationResult>;
629
630#[derive(Debug, Serialize, Deserialize, Clone, Default)]
631#[serde(rename_all = "camelCase")]
632pub struct MarginOCOOrder {
633    pub symbol: String,
634    /// "TRUE" or "FALSE", in upper case, default is "FALSE"
635    pub is_isolated: Option<String>,
636    /// A unique identifier that will be applied to all orders
637    pub list_client_order_id: Option<String>,
638    pub side: OrderSide,
639    pub quantity: f64,
640    /// A unique identifier that will be applied to the limit order
641    pub limit_client_order_id: Option<String>,
642    pub price: f64,
643    pub limit_iceberg_qty: Option<f64>,
644    /// A unique identifier that will be applied to the stop order
645    pub stop_client_order_id: Option<String>,
646    pub stop_price: f64,
647    pub stop_limit_price: Option<f64>,
648    pub stop_iceberg_qty: Option<f64>,
649    pub stop_limit_time_in_force: Option<TimeInForce>,
650    /// Default is `OrderResponse::ACK`
651    pub new_order_resp_type: Option<OrderResponse>,
652    /// Default is `SideEffectType::NoSideEffect`
653    pub side_effect_type: Option<SideEffectType>,
654}
655
656#[derive(Debug, Serialize, Deserialize, Clone)]
657#[serde(rename_all = "camelCase")]
658pub struct MarginOCOOrderResult {
659    pub order_list_id: u64,
660    pub contingency_type: ContingencyType,
661    pub list_status_type: OCOStatus,
662    pub list_order_status: OCOOrderStatus,
663    pub list_client_order_id: Option<String>,
664    pub transaction_time: u128,
665    pub symbol: String,
666    #[serde(default, with = "string_or_float_opt")]
667    pub margin_buy_borrow_amount: Option<f64>,
668    pub margin_buy_borrow_asset: Option<String>,
669    pub is_isolated: Option<bool>,
670    pub orders: Vec<OCOOrderDetail>,
671    pub order_reports: Vec<OCOOrderReport>,
672}
673
674#[derive(Debug, Serialize, Deserialize, Clone)]
675#[serde(rename_all = "camelCase")]
676pub struct OCOOrderDetail {
677    pub symbol: String,
678    pub order_id: u64,
679    pub client_order_id: Option<String>,
680}
681
682#[derive(Debug, Serialize, Deserialize, Clone)]
683#[serde(rename_all = "camelCase")]
684pub struct OCOOrderReport {
685    pub symbol: String,
686    pub order_id: u64,
687    pub client_order_id: Option<String>,
688    pub transact_time: u128,
689    #[serde(with = "string_or_float")]
690    pub price: f64,
691    #[serde(with = "string_or_float")]
692    pub orig_qty: f64,
693    #[serde(with = "string_or_float")]
694    pub executed_qty: f64,
695    #[serde(with = "string_or_float")]
696    pub cummulative_quote_qty: f64,
697    pub status: OrderStatus,
698    pub time_in_force: TimeInForce,
699    #[serde(rename = "type")]
700    pub order_type: OrderType,
701    pub side: OrderSide,
702    #[serde(default, with = "string_or_float_opt")]
703    pub stop_price: Option<f64>,
704    #[serde(default, with = "string_or_float_opt")]
705    pub iceberg_qty: Option<f64>,
706}
707
708/// archived and is_isolated are only applicable to certain endpoints
709/// refer to Binance documentation for full disclosure
710#[derive(Debug, Serialize, Deserialize, Clone, Default)]
711#[serde(rename_all = "camelCase")]
712pub struct RecordsQuery {
713    pub asset: String,
714    pub tx_id: Option<u64>,
715    pub start_time: Option<u64>,
716    pub end_time: Option<u64>,
717    pub current: Option<u16>,
718    pub size: Option<u8>,
719    pub transfer_type: Option<TransferType>,
720    pub archived: Option<bool>,
721    /// "TRUE" or "FALSE", default is "FALSE"
722    pub is_isolated: Option<String>,
723}
724
725#[derive(Debug, Serialize, Deserialize, Clone, Default)]
726#[serde(rename_all = "camelCase")]
727pub struct OCORecordsQuery {
728    pub symbol: Option<String>,
729    pub from_id: Option<u64>,
730    pub start_time: Option<u64>,
731    pub end_time: Option<u64>,
732    pub limit: Option<u8>,
733    /// "TRUE" or "FALSE", default is "FALSE"
734    pub is_isolated: Option<String>,
735}
736
737#[derive(Debug, Serialize, Deserialize, Clone, Default)]
738#[serde(rename_all = "camelCase")]
739pub struct MarginOrdersQuery {
740    pub symbol: String,
741    /// "TRUE" or "FALSE", default is "FALSE"
742    pub is_isolated: Option<String>,
743    pub order_id: u64,
744    pub start_time: Option<u64>,
745    pub end_time: Option<u64>,
746    pub limit: Option<u8>,
747}
748
749#[derive(Debug, Serialize, Deserialize, Clone, Default)]
750#[serde(rename_all = "camelCase")]
751pub struct MarginOwnTradesQuery {
752    pub symbol: String,
753    /// "TRUE" or "FALSE", default is "FALSE"
754    pub is_isolated: Option<String>,
755    pub from_id: u64,
756    pub start_time: Option<u64>,
757    pub end_time: Option<u64>,
758    pub limit: Option<u8>,
759}
760
761/// archived and is_isolated are only applicable to certain endpoints
762/// refer to Binance documentation for full disclosure
763#[derive(Debug, Serialize, Deserialize, Clone, Default)]
764#[serde(rename_all = "camelCase")]
765pub struct IsolatedTransfersQuery {
766    pub symbol: String,
767    pub asset: Option<String>,
768    pub start_time: Option<u64>,
769    pub end_time: Option<u64>,
770    pub current: Option<u16>,
771    pub size: Option<u8>,
772    pub trans_from: Option<IsolatedMarginTransferType>,
773    pub trans_to: Option<IsolatedMarginTransferType>,
774}
775
776#[derive(Debug, Serialize, Deserialize, Clone)]
777#[serde(rename_all = "camelCase")]
778pub struct RepayState {
779    #[serde(with = "string_or_float")]
780    pub amount: f64,
781    pub asset: String,
782    #[serde(with = "string_or_float")]
783    pub interest: f64,
784    #[serde(with = "string_or_float")]
785    pub principal: f64,
786    pub status: TransactionStatus,
787    pub timestamp: u64,
788    pub tx_id: u64,
789    pub isolated_symbol: Option<String>,
790}
791
792#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
793#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
794pub enum TransactionStatus {
795    Pending,
796    Confirmed,
797    Failed,
798    #[serde(other)]
799    Other,
800}
801
802#[derive(Debug, Serialize, Deserialize, Clone)]
803#[serde(rename_all = "camelCase")]
804pub struct LoanState {
805    pub asset: String,
806    #[serde(with = "string_or_float")]
807    pub principal: f64,
808    pub timestamp: u64,
809    pub status: TransactionStatus,
810    pub isolated_symbol: Option<String>,
811    pub tx_id: u64,
812}
813
814#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
815pub enum TransferType {
816    #[serde(rename = "ROLL_IN")]
817    RollIn,
818    #[serde(rename = "ROLL_OUT")]
819    RollOut,
820    #[serde(other)]
821    Other,
822}
823
824#[derive(Debug, Serialize, Deserialize, Clone)]
825#[serde(rename_all = "camelCase")]
826pub struct OrderState {
827    #[serde(with = "string_or_float")]
828    pub amount: f64,
829    pub asset: String,
830    pub status: TransactionStatus,
831    pub timestamp: u64,
832    pub tx_id: u64,
833    #[serde(rename = "type")]
834    pub transfer_type: TransferType,
835}
836
837#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
838#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
839pub enum InterestType {
840    /// First interested charged on borrow
841    OnBorrow,
842    /// Interested charged per hour
843    Periodic,
844    /// Interested charged per hour converted into BNB
845    PeriodicConverted,
846    /// First interested charged on borrow converted into BNB
847    OnBorrowConverted,
848    #[serde(other)]
849    Other,
850}
851
852#[derive(Debug, Serialize, Deserialize, Clone)]
853#[serde(rename_all = "camelCase")]
854pub struct InterestState {
855    pub asset: String,
856    #[serde(with = "string_or_float")]
857    pub interest: f64,
858    pub interest_accured_time: u64,
859    #[serde(with = "string_or_float")]
860    pub interest_rate: f64,
861    #[serde(with = "string_or_float")]
862    pub principal: f64,
863    #[serde(rename = "type")]
864    pub interest_type: InterestType,
865    pub isolated_symbol: Option<String>,
866}
867
868#[derive(Debug, Serialize, Deserialize, Clone)]
869#[serde(rename_all = "camelCase")]
870pub struct ForcedLiquidationState {
871    #[serde(with = "string_or_float")]
872    pub avg_price: f64,
873    #[serde(with = "string_or_float")]
874    pub executed_qty: f64,
875    pub order_id: u64,
876    #[serde(with = "string_or_float")]
877    pub price: f64,
878    #[serde(with = "string_or_float")]
879    pub qty: f64,
880    pub side: OrderSide,
881    pub symbol: String,
882    pub time_in_force: TimeInForce,
883    pub updated_time: u128,
884    pub is_isolated: Option<bool>,
885}
886
887#[derive(Debug, Serialize, Deserialize, Clone)]
888#[serde(rename_all = "camelCase")]
889pub struct RecordsQueryResult<R> {
890    pub rows: Option<Vec<R>>,
891    pub total: u64,
892}
893
894#[derive(Debug, Serialize, Deserialize, Clone)]
895#[serde(rename_all = "camelCase")]
896pub struct UserAsset {
897    pub asset: String,
898    #[serde(with = "string_or_float")]
899    pub borrowed: f64,
900    #[serde(with = "string_or_float")]
901    pub free: f64,
902    #[serde(with = "string_or_float")]
903    pub interest: f64,
904    #[serde(with = "string_or_float")]
905    pub locked: f64,
906    #[serde(with = "string_or_float")]
907    pub net_asset: f64,
908}
909
910pub type UserAssets = Vec<UserAsset>;
911
912#[derive(Debug, Serialize, Deserialize, Clone)]
913#[serde(rename_all = "camelCase")]
914pub struct MarginAccountDetails {
915    pub borrow_enabled: bool,
916    #[serde(with = "string_or_float")]
917    pub margin_level: f64,
918    #[serde(with = "string_or_float")]
919    pub total_asset_of_btc: f64,
920    #[serde(with = "string_or_float")]
921    pub total_liability_of_btc: f64,
922    #[serde(with = "string_or_float")]
923    pub total_net_asset_of_btc: f64,
924    pub trade_enabled: bool,
925    pub transfer_enabled: bool,
926    pub user_assets: UserAssets,
927}
928
929#[derive(Debug, Serialize, Deserialize, Clone)]
930#[serde(rename_all = "camelCase")]
931pub struct IsolatedMarginAccountAsset {
932    pub asset: String,
933    pub borrow_enabled: bool,
934    #[serde(with = "string_or_float")]
935    pub borrowed: f64,
936    #[serde(with = "string_or_float")]
937    pub free: f64,
938    #[serde(with = "string_or_float")]
939    pub interest: f64,
940    #[serde(with = "string_or_float")]
941    pub locked: f64,
942    #[serde(with = "string_or_float")]
943    pub net_asset: f64,
944    #[serde(with = "string_or_float")]
945    pub net_asset_of_btc: f64,
946    pub repay_enabled: bool,
947    #[serde(with = "string_or_float")]
948    pub total_asset: f64,
949}
950
951#[derive(Debug, Serialize, Deserialize, Clone)]
952#[serde(rename_all = "camelCase")]
953pub struct IsolatedMarginAccountAssetDetails {
954    pub base_asset: IsolatedMarginAccountAsset,
955    pub quote_asset: IsolatedMarginAccountAsset,
956    pub symbol: String,
957    pub isolated_created: bool,
958    pub enabled: bool,
959    #[serde(with = "string_or_float")]
960    pub margin_level: f64,
961    #[serde(with = "string_or_float")]
962    pub margin_ratio: f64,
963    pub margin_level_status: MarginLevelStatus,
964    #[serde(with = "string_or_float")]
965    pub index_price: f64,
966    #[serde(with = "string_or_float")]
967    pub liquidate_price: f64,
968    #[serde(with = "string_or_float")]
969    pub liquidate_rate: f64,
970    pub trade_enabled: bool,
971}
972
973#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
974#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
975pub enum MarginLevelStatus {
976    Excessive,
977    Normal,
978    MarginCall,
979    PreLiquidation,
980    ForceLiquidation,
981    #[serde(other)]
982    Other,
983}
984
985#[derive(Debug, Serialize, Deserialize, Clone)]
986#[serde(rename_all = "camelCase")]
987pub struct IsolatedMarginAccountDetails {
988    pub assets: Vec<IsolatedMarginAccountAssetDetails>,
989    #[serde(default, with = "string_or_float_opt")]
990    pub total_asset_of_btc: Option<f64>,
991    #[serde(default, with = "string_or_float_opt")]
992    pub total_liability_of_btc: Option<f64>,
993    #[serde(default, with = "string_or_float_opt")]
994    pub total_net_asset_of_btc: Option<f64>,
995}
996
997#[derive(Debug, Serialize, Deserialize, Clone)]
998#[serde(rename_all = "camelCase")]
999pub struct AssetQuery {
1000    pub asset: String,
1001}
1002
1003#[derive(Debug, Serialize, Deserialize, Clone)]
1004#[serde(rename_all = "camelCase")]
1005pub struct MarginAssetQuery {
1006    pub asset: String,
1007    pub isolated_symbol: Option<String>,
1008}
1009
1010#[derive(Debug, Serialize, Deserialize, Clone)]
1011#[serde(rename_all = "camelCase")]
1012pub struct AssetDetails {
1013    pub asset_full_name: String,
1014    pub asset_name: String,
1015    pub is_borrowable: bool,
1016    pub is_mortgageable: bool,
1017    #[serde(with = "string_or_float")]
1018    pub user_min_borrow: f64,
1019    #[serde(with = "string_or_float")]
1020    pub user_min_repay: f64,
1021}
1022
1023#[derive(Debug, Serialize, Deserialize, Clone)]
1024#[serde(rename_all = "camelCase")]
1025pub struct PairQuery {
1026    pub symbol: String,
1027}
1028
1029#[derive(Debug, Serialize, Deserialize, Clone)]
1030#[serde(rename_all = "camelCase")]
1031pub struct MarginPairQuery {
1032    pub symbol: String,
1033    pub is_isolated: Option<String>,
1034}
1035
1036#[derive(Debug, Serialize, Deserialize, Clone)]
1037#[serde(rename_all = "camelCase")]
1038pub struct IsolatedMarginPairQuery {
1039    pub symbols: String,
1040}
1041
1042#[derive(Debug, Serialize, Deserialize, Clone)]
1043#[serde(rename_all = "camelCase")]
1044pub struct PairAndWindowQuery {
1045    pub symbol: String,
1046    pub recv_window: u64,
1047}
1048
1049#[derive(Debug, Serialize, Deserialize, Clone)]
1050#[serde(rename_all = "camelCase")]
1051pub struct PairDetails {
1052    pub id: u128,
1053    pub symbol: String,
1054    pub base: String,
1055    pub quote: String,
1056    pub is_margin_trade: bool,
1057    pub is_buy_allowed: bool,
1058    pub is_sell_allowed: bool,
1059}
1060
1061pub type AllAssets = Vec<AssetDetails>;
1062
1063pub type AllPairs = Vec<PairDetails>;
1064
1065#[derive(Debug, Serialize, Deserialize, Clone)]
1066#[serde(rename_all = "camelCase")]
1067pub struct IsolatedPairDetails {
1068    pub symbol: String,
1069    pub base: String,
1070    pub quote: String,
1071    pub is_margin_trade: bool,
1072    pub is_buy_allowed: bool,
1073    pub is_sell_allowed: bool,
1074}
1075
1076pub type AllIsolatedPairs = Vec<IsolatedPairDetails>;
1077
1078#[derive(Debug, Serialize, Deserialize, Clone)]
1079#[serde(rename_all = "camelCase")]
1080pub struct PriceIndex {
1081    pub calc_time: u128,
1082    #[serde(with = "string_or_float")]
1083    pub price: f64,
1084    pub symbol: String,
1085}
1086
1087#[derive(Default, Debug, Serialize, Deserialize, Clone)]
1088#[serde(rename_all = "camelCase")]
1089pub struct MarginOrderQuery {
1090    pub symbol: String,
1091    pub is_isolated: Option<String>,
1092    pub order_id: Option<String>,
1093    pub orig_client_order_id: Option<String>,
1094}
1095
1096#[derive(Debug, Serialize, Deserialize, Clone)]
1097#[serde(rename_all = "camelCase")]
1098pub struct MarginOrderResult {
1099    pub symbol: String,
1100    #[serde(with = "string_or_u64")]
1101    pub order_id: u64,
1102    pub client_order_id: String,
1103    pub transact_time: u128,
1104    #[serde(with = "string_or_float")]
1105    pub price: f64,
1106    #[serde(with = "string_or_float")]
1107    pub orig_qty: f64,
1108    #[serde(with = "string_or_float")]
1109    pub executed_qty: f64,
1110    #[serde(with = "string_or_float")]
1111    pub cummulative_quote_qty: f64,
1112    pub status: OrderStatus,
1113    pub time_in_force: TimeInForce,
1114    #[serde(rename(serialize = "type", deserialize = "type"))]
1115    pub order_type: OrderType,
1116    pub side: OrderSide,
1117    #[serde(default, with = "string_or_float_opt")]
1118    pub margin_buy_borrow_amount: Option<f64>,
1119    pub margin_buy_borrow_asset: Option<String>,
1120    pub is_isolated: Option<bool>,
1121    pub fills: Vec<Fill>,
1122}
1123
1124#[derive(Debug, Serialize, Deserialize, Clone)]
1125#[serde(rename_all = "camelCase")]
1126pub struct MarginOrderState {
1127    pub client_order_id: String,
1128    #[serde(with = "string_or_float")]
1129    pub cummulative_quote_qty: f64,
1130    #[serde(with = "string_or_float")]
1131    pub executed_qty: f64,
1132    #[serde(with = "string_or_float")]
1133    pub iceberg_qty: f64,
1134    pub is_working: bool,
1135    pub order_id: u64,
1136    #[serde(with = "string_or_float")]
1137    pub orig_qty: f64,
1138    #[serde(with = "string_or_float")]
1139    pub price: f64,
1140    pub side: OrderSide,
1141    pub status: OrderStatus,
1142    #[serde(with = "string_or_float")]
1143    pub stop_price: f64,
1144    pub symbol: String,
1145    pub is_isolated: Option<bool>,
1146    pub time: u64,
1147    pub time_in_force: TimeInForce,
1148    #[serde(rename(serialize = "type", deserialize = "type"))]
1149    pub order_type: OrderType,
1150    pub update_time: u64,
1151}
1152
1153#[derive(Debug, Serialize, Deserialize, Clone)]
1154#[serde(rename_all = "camelCase")]
1155pub struct OrderSumaryState {
1156    pub id: u64,
1157    pub price: f64,
1158    pub qty: f64,
1159    pub quote_qty: f64,
1160    pub symbol: String,
1161    pub time: u128,
1162}
1163
1164#[derive(Debug, Serialize, Deserialize, Clone)]
1165#[serde(rename_all = "camelCase")]
1166pub struct OwnTradesState {
1167    #[serde(with = "string_or_float")]
1168    pub commission: f64,
1169    pub commission_asset: String,
1170    pub id: u64,
1171    pub is_best_match: bool,
1172    pub is_buyer: bool,
1173    pub is_maker: bool,
1174    pub order_id: u64,
1175    #[serde(with = "string_or_float")]
1176    pub price: f64,
1177    #[serde(with = "string_or_float")]
1178    pub qty: f64,
1179    pub symbol: String,
1180    pub time: u128,
1181    pub is_isolated: bool,
1182}
1183
1184#[derive(Debug, Serialize, Deserialize, Clone)]
1185#[serde(rename_all = "camelCase")]
1186pub struct MaxBorrowableAmount {
1187    #[serde(with = "string_or_float")]
1188    pub amount: f64,
1189    #[serde(with = "string_or_float")]
1190    pub borrow_limit: f64,
1191}
1192
1193#[derive(Debug, Serialize, Deserialize, Clone)]
1194#[serde(rename_all = "camelCase")]
1195pub struct MaxTransferableAmount {
1196    #[serde(with = "string_or_float")]
1197    pub amount: f64,
1198}
1199
1200#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
1201#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
1202pub enum SymbolStatus {
1203    PreTrading,
1204    Trading,
1205    PostTrading,
1206    EndOfDay,
1207    Halt,
1208    AuctionMatch,
1209    Break,
1210    PendingTrading,
1211    #[serde(other)]
1212    Other,
1213}
1214
1215#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
1216#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
1217pub enum SymbolPermission {
1218    Spot,
1219    Margin,
1220    #[serde(other)]
1221    Other,
1222}
1223
1224/// Status of an order, this can typically change over time
1225#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
1226#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
1227pub enum OrderStatus {
1228    /// The order has been accepted by the engine.
1229    New,
1230    /// A part of the order has been filled.
1231    PartiallyFilled,
1232    /// The order has been completely filled.
1233    Filled,
1234    /// The order has been canceled by the user.
1235    Canceled,
1236    /// (currently unused)
1237    PendingCancel,
1238    /// The order was not accepted by the engine and not processed.
1239    Rejected,
1240    /// The order was canceled according to the order type's rules (e.g. LIMIT FOK orders with no fill, LIMIT IOC or MARKET orders that partially fill) or by the exchange, (e.g. orders canceled during liquidation, orders canceled during maintenance)
1241    Expired,
1242    /// Part of the order or all of the order's quantity has filled.
1243    Trade,
1244}
1245
1246#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
1247#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
1248pub enum OCOStatus {
1249    Response,
1250    ExecStarted,
1251    AllDone,
1252}
1253
1254#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
1255#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
1256pub enum OCOOrderStatus {
1257    Executing,
1258    AllDone,
1259    Reject,
1260}
1261
1262#[derive(Debug, Serialize, Deserialize, Clone)]
1263#[serde(rename_all = "camelCase")]
1264pub struct MarginOCOOrderCancellation {
1265    pub symbol: String,
1266    pub order_list_id: u64,
1267    pub list_client_order_id: String,
1268    pub new_client_order_id: String,
1269    pub is_isolated: Option<String>,
1270}
1271
1272#[derive(Debug, Serialize, Deserialize, Clone, Default)]
1273#[serde(rename_all = "camelCase")]
1274pub struct MarginOCOOrderQuery {
1275    pub symbol: Option<String>,
1276    pub is_isolated: Option<String>,
1277    pub order_list_id: Option<String>,
1278    pub orig_client_order_id: Option<String>,
1279}
1280
1281#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
1282#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
1283pub enum ContingencyType {
1284    OCO,
1285    #[serde(other)]
1286    Other,
1287}
1288
1289/// API Rate Limit
1290/// Example
1291/// {
1292///   "rateLimitType": "REQUEST_WEIGHT",
1293///   "interval": "MINUTE",
1294///   "intervalNum": 1,
1295///   "limit": 1200
1296/// }
1297///
1298#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
1299#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
1300pub enum RateLimitType {
1301    RequestWeight,
1302    Orders,
1303    RawRequests,
1304    #[serde(other)]
1305    Other,
1306}
1307
1308/// Rate Limit Interval, used by RateLimitType
1309#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
1310#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
1311pub enum RateLimitInterval {
1312    Second,
1313    Minute,
1314    Day,
1315}
1316
1317#[derive(Debug, Serialize, Deserialize, Clone)]
1318#[serde(rename_all = "camelCase")]
1319pub struct RateLimit {
1320    pub interval: RateLimitInterval,
1321    pub rate_limit_type: RateLimitType,
1322    pub interval_num: i32,
1323    pub limit: i32,
1324}
1325
1326#[derive(Debug, Serialize, Deserialize, Clone, Default)]
1327#[serde(rename_all = "camelCase")]
1328pub struct BnbBurnQuery {
1329    /// "true" or "false", defaults to "false"
1330    #[serde(rename = "spotBNBBurn")]
1331    pub spot_bnb_burn: Option<String>,
1332    /// "true" or "false", defaults to "false"
1333    #[serde(rename = "interestBNBBurn")]
1334    pub interest_bnb_burn: Option<String>,
1335}
1336
1337#[derive(Debug, Serialize, Deserialize, Clone)]
1338pub struct BnbBurnStatus {
1339    #[serde(rename = "spotBNBBurn")]
1340    pub spot_bnb_burn: Option<bool>,
1341    #[serde(rename = "interestBNBBurn")]
1342    pub interest_bnb_burn: Option<bool>,
1343}
1344
1345#[derive(Debug, Serialize, Deserialize, Clone, Default)]
1346#[serde(rename_all = "camelCase")]
1347pub struct InterestRateHistoryQuery {
1348    pub asset: String,
1349    pub vip_level: Option<u8>,
1350    pub start_time: Option<u64>,
1351    pub end_time: Option<u64>,
1352    pub limit: Option<u64>,
1353}
1354
1355#[derive(Debug, Serialize, Deserialize, Clone)]
1356#[serde(rename_all = "camelCase")]
1357pub struct InterestRateAssetHistory {
1358    pub asset: String,
1359    #[serde(with = "string_or_float")]
1360    pub daily_interest_rate: f64,
1361    pub timestamp: u128,
1362    pub vip_level: u8,
1363}
1364
1365pub type InterestRateHistory = Vec<InterestRateAssetHistory>;
1366
1367#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
1368#[serde(rename_all = "camelCase")]
1369pub struct KlineSummary {
1370    pub open_time: i64,
1371    pub open: f64,
1372    pub high: f64,
1373    pub low: f64,
1374    pub close: f64,
1375    pub volume: f64,
1376    pub close_time: i64,
1377    pub quote_asset_volume: f64,
1378    pub number_of_trades: i64,
1379    pub taker_buy_base_asset_volume: f64,
1380    pub taker_buy_quote_asset_volume: f64,
1381}
1382
1383#[derive(Serialize, Deserialize, Debug, Clone)]
1384pub struct PropertyCmd {
1385    pub id: i32,
1386    pub method: String,
1387    pub params: (String, bool),
1388}
1389
1390#[derive(Serialize, Deserialize, Debug, Clone)]
1391#[serde(rename_all = "camelCase")]
1392pub struct IsolatedAccountLimit {
1393    pub enabled_account: u64,
1394    pub max_account: u64,
1395}
1396
1397#[derive(Serialize, Deserialize, Debug, Clone)]
1398#[serde(rename_all = "camelCase")]
1399pub struct IsolatedSymbol {
1400    pub symbol: String,
1401    pub max_account: u64,
1402}
1403
1404#[derive(Serialize, Deserialize, Debug, Clone)]
1405pub struct SystemStatus {
1406    pub status: u64,
1407    pub msg: String,
1408}
1409
1410#[derive(Serialize, Deserialize, Debug, Clone)]
1411#[serde(rename_all = "camelCase")]
1412pub struct WalletCoinInfo {
1413    pub coin: String,
1414    pub deposit_all_enable: bool,
1415    #[serde(with = "string_or_float")]
1416    pub free: f64,
1417    #[serde(with = "string_or_float")]
1418    pub freeze: f64,
1419    #[serde(with = "string_or_float")]
1420    pub ipoable: f64,
1421    #[serde(with = "string_or_float")]
1422    pub ipoing: f64,
1423    pub is_legal_money: bool,
1424    #[serde(with = "string_or_float")]
1425    pub locked: f64,
1426    pub name: String,
1427    pub network_list: Vec<CoinNetwork>,
1428    #[serde(with = "string_or_float")]
1429    pub storage: f64,
1430    pub trading: bool,
1431    pub withdraw_all_enable: bool,
1432    #[serde(with = "string_or_float")]
1433    pub withdrawing: f64,
1434}
1435
1436#[derive(Serialize, Deserialize, Debug, Clone)]
1437#[serde(rename_all = "camelCase")]
1438pub struct CoinNetwork {
1439    pub address_regex: String,
1440    pub coin: String,
1441    #[serde(default)]
1442    pub deposit_desc: String,
1443    pub deposit_enable: bool,
1444    pub is_default: bool,
1445    pub memo_regex: String,
1446    pub min_confirm: u32,
1447    pub name: String,
1448    pub network: String,
1449    pub reset_address_status: bool,
1450    pub special_tips: Option<String>,
1451    pub un_lock_confirm: u32,
1452    #[serde(default)]
1453    pub withdraw_desc: String,
1454    pub withdraw_enable: bool,
1455    #[serde(with = "string_or_float")]
1456    pub withdraw_fee: f64,
1457    #[serde(with = "string_or_float")]
1458    pub withdraw_integer_multiple: f64,
1459    #[serde(with = "string_or_float")]
1460    pub withdraw_max: f64,
1461    #[serde(with = "string_or_float")]
1462    pub withdraw_min: f64,
1463    #[serde(default)]
1464    pub same_address: bool,
1465}
1466
1467#[derive(Serialize, Deserialize, Debug, Clone)]
1468#[serde(rename_all = "camelCase")]
1469pub struct AccountSnapshot {
1470    pub code: u32,
1471    pub msg: String,
1472    pub snapshot_vos: Vec<SnapshotVos>,
1473}
1474
1475#[derive(Serialize, Deserialize, Debug, Clone)]
1476#[serde(rename_all = "camelCase")]
1477pub struct SnapshotVos {
1478    pub data: SnapshotVosData,
1479    #[serde(rename = "type")]
1480    pub snapshot_type: String,
1481    pub update_time: u64,
1482}
1483
1484#[derive(Serialize, Deserialize, Debug, Clone)]
1485#[serde(rename_all = "camelCase")]
1486pub struct SnapshotVosData {
1487    pub balances: Vec<Balance>,
1488    #[serde(with = "string_or_float")]
1489    pub total_asset_of_btc: f64,
1490}
1491
1492#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
1493#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
1494pub enum AccountSnapshotType {
1495    Spot,
1496    Margin,
1497    Futures,
1498}
1499
1500#[derive(Debug, Serialize, Deserialize, Clone)]
1501#[serde(rename_all = "camelCase")]
1502pub struct AccountSnapshotQuery {
1503    #[serde(rename = "type")]
1504    pub account_type: AccountSnapshotType,
1505    pub start_time: Option<u64>,
1506    pub end_time: Option<u64>,
1507    pub limit: Option<u64>,
1508}
1509
1510#[derive(Debug, Serialize, Deserialize, Clone, Default)]
1511#[serde(rename_all = "camelCase")]
1512pub struct CoinWithdrawalQuery {
1513    pub coin: String,
1514    /// client id for withdraw
1515    pub withdraw_order_id: Option<String>,
1516    pub network: Option<String>,
1517    pub address: String,
1518    /// Secondary address identifier for coins like XRP,XMR etc.
1519    pub address_tag: Option<String>,
1520    pub amount: f64,
1521    /// When making internal transfer, true for returning the fee to the destination account; false for returning the fee back to the departure account. Default false.
1522    pub transaction_fee_flag: Option<bool>,
1523    /// Description of the address. Space in name should be encoded into %20.
1524    pub name: Option<String>,
1525    /// The wallet type for withdraw,0: spot wallet. 1: funding wallet. Default:  spot wallet
1526    pub wallet_type: u8,
1527}
1528
1529#[derive(Debug, Serialize, Deserialize, Clone, Default)]
1530#[serde(rename_all = "camelCase")]
1531pub struct DepositHistoryQuery {
1532    pub coin: Option<String>,
1533    /// 0(0:pending,6: credited but cannot withdraw, 1:success)
1534    pub status: Option<u16>,
1535    /// Default: 90 days from current timestamp
1536    pub start_time: Option<u64>,
1537    /// Default: present timestamp
1538    pub end_time: Option<u64>,
1539    /// Default:1000, Max:1000
1540    pub limit: Option<u64>,
1541    /// Default: present timestamp
1542    pub offset: Option<u64>,
1543}
1544
1545#[derive(Debug, Serialize, Deserialize, Clone, Default)]
1546#[serde(rename_all = "camelCase")]
1547pub struct DepositRecord {
1548    pub coin: String,
1549    #[serde(with = "string_or_float")]
1550    pub amount: f64,
1551    pub network: String,
1552    pub status: u8,
1553    pub address: String,
1554    pub address_tag: Option<String>,
1555    pub tx_id: String,
1556    pub insert_time: Option<u64>,
1557    pub transfer_type: u8,
1558    #[serde(default)]
1559    pub unlock_confirm: u32,
1560    pub confirm_times: String,
1561    pub wallet_type: Option<u32>,
1562}
1563
1564#[derive(Debug, Serialize, Deserialize, Clone, Default)]
1565#[serde(rename_all = "camelCase")]
1566pub struct WithdrawalHistoryQuery {
1567    pub coin: Option<String>,
1568    pub withdraw_order_id: Option<String>,
1569    /// 0(0:Email Sent,1:Cancelled 2:Awaiting Approval 3:Rejected 4:Processing 5:Failure 6:Completed)
1570    pub status: Option<u16>,
1571    /// Default: 90 days from current timestamp
1572    pub start_time: Option<u64>,
1573    /// Default: present timestamp
1574    pub end_time: Option<u64>,
1575    /// Default:1000, Max:1000
1576    pub limit: Option<u64>,
1577    /// Default: present timestamp
1578    pub offset: Option<u64>,
1579}
1580
1581#[derive(Debug, Serialize, Deserialize, Clone)]
1582#[serde(rename_all = "camelCase")]
1583pub struct RecordHistory<T> {
1584    pub start_at: DateTime<Utc>,
1585    pub end_at: DateTime<Utc>,
1586    pub records: Vec<T>,
1587}
1588
1589#[derive(Debug, Serialize, Deserialize, Clone, Default)]
1590#[serde(rename_all = "camelCase")]
1591pub struct WithdrawalRecord {
1592    pub address: String,
1593    #[serde(with = "string_or_float")]
1594    pub amount: f64,
1595    pub apply_time: String,
1596    pub coin: String,
1597    pub id: String,
1598    /// // will not be returned if there's no withdrawOrderId for this withdraw.
1599    pub withdraw_order_id: Option<String>,
1600    pub network: String,
1601    /// 1 for internal transfer, 0 for external transfer
1602    pub transfer_type: u8,
1603    pub status: u8,
1604    #[serde(with = "string_or_float")]
1605    pub transaction_fee: f64,
1606    /// // confirm times for withdraw
1607    pub confirm_no: Option<u64>,
1608    pub info: Option<String>,
1609    pub tx_id: String,
1610}
1611
1612#[cfg(feature = "wallet_api")]
1613#[derive(Debug, Serialize, Deserialize, Clone, Default)]
1614#[serde(rename_all = "camelCase")]
1615pub struct DepositAddressQuery {
1616    pub coin: String,
1617    /// If network is not send, return with default network of the coin.
1618    /// You can get network and isDefault in networkList in the response [`crate::wallet::Wallet::all_coin_info`]
1619    pub network: Option<String>,
1620}
1621
1622#[derive(Debug, Serialize, Deserialize, Clone, Default)]
1623#[serde(rename_all = "camelCase")]
1624pub struct DepositAddress {
1625    pub coin: String,
1626    pub address: String,
1627    pub tag: Option<String>,
1628    pub url: Option<String>,
1629}
1630
1631#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
1632#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
1633pub enum UniversalTransferType {
1634    /// Spot account transfer to USDⓈ-M Futures account
1635    MainUmfuture,
1636    /// Spot account transfer to COIN-M Futures account
1637    MainCmfuture,
1638    /// Spot account transfer to Margin (cross) account
1639    MainMargin,
1640    /// USDⓈ-M Futures account transfer to Spot account
1641    UmfutureMain,
1642    /// USDⓈ-M Futures account transfer to Margin (cross) account
1643    UmFutureMargin,
1644    /// COIN-M Futures account transfer to Spot account
1645    CmfutureMain,
1646    /// COIN-M Futures account transfer to Margin(cross) account
1647    CmfutureMargin,
1648    /// Margin(cross)account transfer to Spot account
1649    MarginMain,
1650    /// Margin (cross) account transfer to USDⓈ-M Futures
1651    MarginUmfuture,
1652    /// Margin (cross) account transfer to COIN-M Futures
1653    MarginCmfuture,
1654    /// Isolated margin account transfer to Margin (cross) account
1655    IsolatedmarginMargin,
1656    /// Margin (cross) account transfer to Isolated margin account
1657    MarginIsolatedmargin,
1658    /// Isolated margin account transfer to Isolated margin account
1659    IsolatedmarginIsolatedmargin,
1660    /// Spot account transfer to Funding account
1661    MainFunding,
1662    /// Funding account transfer to Spot account
1663    FundingMain,
1664    /// Funding account transfer to UMFUTURE account
1665    FundingUmfuture,
1666    /// UMFUTURE account transfer to Funding account
1667    UmfutureFunding,
1668    /// MARGIN account transfer to Funding account
1669    MarginFunding,
1670    /// Funding account transfer to Margin account
1671    FundingMargin,
1672    /// Funding account transfer to CMFUTURE account
1673    FundingCmfuture,
1674    /// CMFUTURE account transfer to Funding account
1675    CmfutureFunding,
1676}
1677
1678#[derive(Debug, Serialize, Deserialize, Clone)]
1679#[serde(rename_all = "camelCase")]
1680pub struct UniversalTransfer {
1681    pub asset: String,
1682    pub amount: f64,
1683    pub from_symbol: Option<String>,
1684    pub to_symbol: Option<String>,
1685    #[serde(rename(serialize = "type", deserialize = "type"))]
1686    pub transfer_type: UniversalTransferType,
1687}
1688
1689#[derive(Debug, Serialize, Deserialize, Clone)]
1690#[serde(rename_all = "camelCase")]
1691pub struct UniversalTransferHistoryQuery {
1692    #[serde(rename(serialize = "type", deserialize = "type"))]
1693    pub transfer_type: UniversalTransferType,
1694    pub start_time: Option<u64>,
1695    pub end_time: Option<u64>,
1696    /// Default : 1
1697    pub current: Option<u64>,
1698    /// Default 10, Max 100
1699    pub size: Option<u64>,
1700    pub from_symbol: Option<String>,
1701    pub to_symbol: Option<String>,
1702}
1703
1704#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
1705#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
1706pub enum UniversalTransferStatus {
1707    Confirmed,
1708    Pending,
1709    Failed,
1710}
1711
1712#[derive(Debug, Serialize, Deserialize, Clone)]
1713#[serde(rename_all = "camelCase")]
1714pub struct UniversalTransferRecord {
1715    pub asset: String,
1716    #[serde(with = "string_or_float")]
1717    pub amount: f64,
1718    #[serde(rename(serialize = "type", deserialize = "type"))]
1719    pub transfer_type: UniversalTransferType,
1720    pub status: UniversalTransferStatus,
1721    pub tran_id: u64,
1722    pub timestamp: u64,
1723}
1724
1725#[derive(Debug, Serialize, Deserialize, Clone)]
1726#[serde(rename_all = "camelCase")]
1727pub struct AccountStatus {
1728    pub data: String,
1729}
1730
1731#[derive(Debug, Serialize, Deserialize, Clone)]
1732#[serde(rename_all = "camelCase")]
1733pub struct ApiTradingStatus {
1734    pub data: ApiTradingStatusData,
1735}
1736
1737#[derive(Debug, Serialize, Deserialize, Clone)]
1738#[serde(rename_all = "camelCase")]
1739pub struct ApiTradingStatusData {
1740    /// API trading function is locked or not
1741    pub is_locked: bool,
1742    /// If API trading function is locked, this is the planned recover time
1743    pub planned_recovery_time: Option<u64>,
1744    pub trigger_condition: ApiTradingStatusTriggerCondition,
1745    pub update_time: Option<u64>,
1746}
1747
1748#[derive(Debug, Serialize, Deserialize, Clone)]
1749#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
1750pub struct ApiTradingStatusTriggerCondition {
1751    /// Number of GTC orders
1752    pub gcr: i64,
1753    /// Number of FOK/IOC orders
1754    pub ifer: i64,
1755    /// Number of orders
1756    pub ufr: i64,
1757}
1758
1759#[derive(Debug, Serialize, Deserialize, Clone)]
1760#[serde(rename_all = "camelCase")]
1761pub struct DustLog {
1762    /// Total counts of exchange
1763    pub total: u64,
1764    pub user_asset_dribblets: Vec<UserAssetDribblet>,
1765}
1766
1767#[derive(Debug, Serialize, Deserialize, Clone)]
1768#[serde(rename_all = "camelCase")]
1769pub struct UserAssetDribblet {
1770    pub operate_time: u64,
1771    /// Total transfered BNB amount for this exchange.
1772    #[serde(with = "string_or_float")]
1773    pub total_transfered_amount: f64,
1774    ///Total service charge amount for this exchange.
1775    #[serde(with = "string_or_float")]
1776    pub total_service_charge_amount: f64,
1777    pub trans_id: u64,
1778    pub user_asset_dribblet_details: Vec<UserAssetDribbletDetail>,
1779}
1780
1781#[derive(Debug, Serialize, Deserialize, Clone)]
1782#[serde(rename_all = "camelCase")]
1783pub struct UserAssetDribbletDetail {
1784    pub trans_id: u64,
1785    #[serde(with = "string_or_float")]
1786    pub amount: f64,
1787    #[serde(with = "string_or_float")]
1788    pub transfered_amount: f64,
1789    #[serde(with = "string_or_float")]
1790    pub service_charge_amount: f64,
1791    pub operate_time: u64,
1792    pub from_asset: String,
1793}
1794
1795#[derive(Debug, Serialize, Deserialize, Clone)]
1796#[serde(rename_all = "camelCase")]
1797pub struct ConvertibleAssets {
1798    pub details: Vec<ConvertibleAssetDetails>,
1799    #[serde(with = "string_or_float")]
1800    #[serde(rename = "totalTransferBtc")]
1801    pub total_transfer_btc: f64,
1802    #[serde(with = "string_or_float")]
1803    #[serde(rename = "totalTransferBNB")]
1804    pub total_transfer_bnb: f64,
1805    #[serde(with = "string_or_float_opt", default)]
1806    pub driblet_percentage: Option<f64>,
1807}
1808
1809#[derive(Debug, Serialize, Deserialize, Clone)]
1810#[serde(rename_all = "camelCase")]
1811pub struct ConvertibleAssetDetails {
1812    pub asset: String,
1813    pub asset_full_name: String,
1814    #[serde(with = "string_or_float")]
1815    pub amount_free: f64,
1816    #[serde(with = "string_or_float")]
1817    #[serde(rename = "toBNB")]
1818    pub to_bnb: f64,
1819    #[serde(with = "string_or_float")]
1820    #[serde(rename = "toBTC")]
1821    pub to_btc: f64,
1822    #[serde(with = "string_or_float")]
1823    #[serde(rename = "toBNBOffExchange")]
1824    pub to_bnb_off_exchange: f64,
1825    #[serde(with = "string_or_float")]
1826    pub exchange: f64,
1827}
1828
1829#[derive(Debug, Serialize, Deserialize, Clone)]
1830#[serde(rename_all = "camelCase")]
1831pub struct DustTransfer {
1832    #[serde(with = "string_or_float")]
1833    pub total_service_charge: f64,
1834    #[serde(with = "string_or_float")]
1835    pub total_transferred: f64,
1836    pub transfer_result: Vec<DustTransferResult>,
1837}
1838
1839#[derive(Debug, Serialize, Deserialize, Clone)]
1840#[serde(rename_all = "camelCase")]
1841pub struct DustTransferResult {
1842    #[serde(with = "string_or_float")]
1843    pub amount: f64,
1844    pub from_asset: String,
1845    pub operate_time: u64,
1846    #[serde(with = "string_or_float")]
1847    pub service_charge_amount: f64,
1848    pub tran_id: u64,
1849    #[serde(with = "string_or_float")]
1850    pub transfered_amount: f64,
1851}
1852
1853#[derive(Debug, Serialize, Deserialize, Clone)]
1854#[serde(rename_all = "camelCase")]
1855pub struct AssetDividend {
1856    pub id: u64,
1857    #[serde(with = "string_or_float")]
1858    pub amount: f64,
1859    pub asset: String,
1860    pub div_time: u64,
1861    pub en_info: String,
1862    pub tran_id: u64,
1863}
1864
1865#[derive(Debug, Serialize, Deserialize, Clone, Default)]
1866#[serde(rename_all = "camelCase")]
1867pub struct AssetDividendQuery {
1868    pub asset: Option<String>,
1869    pub start_time: Option<u64>,
1870    pub end_time: Option<u64>,
1871    /// Default 20, max 500
1872    pub limit: Option<u64>,
1873}
1874
1875pub type SupportedAssetDetails = HashMap<String, SupportedAssetDetail>;
1876
1877#[derive(Debug, Serialize, Deserialize, Clone)]
1878#[serde(rename_all = "camelCase")]
1879pub struct SupportedAssetDetail {
1880    /// min withdraw amount
1881    #[serde(with = "string_or_float_opt")]
1882    #[serde(rename = "minWithdrawAmount")]
1883    pub min_withdrawal_amount: Option<f64>,
1884    /// deposit status (false if ALL of networks' are false)
1885    pub deposit_status: bool,
1886    /// withdraw fee
1887    #[serde(with = "string_or_float_opt")]
1888    pub withdraw_fee: Option<f64>,
1889    /// withdraw status (false if ALL of networks' are false)
1890    pub withdraw_status: bool,
1891    /// reason
1892    pub deposit_tip: Option<String>,
1893}
1894
1895pub type TradeFees = Vec<TradeFee>;
1896
1897#[derive(Debug, Serialize, Deserialize, Clone)]
1898#[serde(rename_all = "camelCase")]
1899pub struct TradeFee {
1900    pub symbol: String,
1901    #[serde(with = "string_or_float")]
1902    pub maker_commission: f64,
1903    #[serde(with = "string_or_float")]
1904    pub taker_commission: f64,
1905}
1906
1907pub type WalletFundings = Vec<WalletFunding>;
1908
1909#[derive(Debug, Serialize, Deserialize, Clone)]
1910#[serde(rename_all = "camelCase")]
1911pub struct WalletFunding {
1912    pub asset: String,
1913    #[serde(with = "string_or_float")]
1914    pub free: f64,
1915    #[serde(with = "string_or_float")]
1916    pub locked: f64,
1917    #[serde(with = "string_or_float")]
1918    pub freeze: f64,
1919    #[serde(with = "string_or_float")]
1920    pub withdrawing: f64,
1921    #[serde(with = "string_or_float")]
1922    pub btc_valuation: f64,
1923}
1924
1925#[derive(Debug, Serialize, Deserialize, Clone)]
1926#[serde(rename_all = "camelCase")]
1927pub struct ApiKeyPermissions {
1928    ip_restrict: bool,
1929    create_time: u64,
1930    /// This option allows you to withdraw via API. You must apply the IP Access Restriction filter in order to enable withdrawals
1931    enable_withdrawals: bool,
1932    /// This option authorizes this key to transfer funds between your master account and your sub account instantly
1933    enable_internal_transfer: bool,
1934    /// Authorizes this key to be used for a dedicated universal transfer API to transfer multiple supported currencies. Each business's own transfer API rights are not affected by this authorization
1935    permits_universal_transfer: bool,
1936    ///  Authorizes this key to Vanilla options trading
1937    enable_vanilla_options: bool,
1938    enable_reading: bool,
1939    ///  API Key created before your futures account opened does not support futures API service
1940    enable_futures: bool,
1941    ///  This option can be adjusted after the Cross Margin account transfer is completed
1942    enable_margin: bool,
1943    /// Spot and margin trading
1944    enable_spot_and_margin_trading: bool,
1945    /// Expiration time for spot and margin trading permission
1946    trading_authority_expiration_time: Option<u64>,
1947}
1948
1949pub type WalletBalances = Vec<WalletBalance>;
1950
1951#[derive(Debug, Serialize, Deserialize, Clone)]
1952#[serde(rename_all = "camelCase")]
1953pub struct WalletBalance {
1954    /// Shows whether the wallet is activated or not
1955    activate: bool,
1956    /// Shows the overall balance of the wallet quoted in BTC
1957    balance: String,
1958    /// Indicates the wallet type: 'Spot', 'Funding', 'Cross Margin', 'Isolated Margin', 'USDⓈ-M Futures', 'COIN-M Futures', 'Earn', 'Options', 'Trading Bots'
1959    wallet_name: String,
1960}
1961
1962pub mod string_or_float {
1963    use std::fmt;
1964
1965    use serde::{de, Deserialize, Deserializer, Serializer};
1966
1967    pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
1968    where
1969        T: fmt::Display,
1970        S: Serializer,
1971    {
1972        serializer.collect_str(value)
1973    }
1974
1975    pub fn deserialize<'de, D>(deserializer: D) -> Result<f64, D::Error>
1976    where
1977        D: Deserializer<'de>,
1978    {
1979        #[derive(Deserialize)]
1980        #[serde(untagged)]
1981        enum StringOrFloat {
1982            String(String),
1983            Float(f64),
1984        }
1985
1986        match StringOrFloat::deserialize(deserializer)? {
1987            StringOrFloat::String(s) => s.parse().map_err(de::Error::custom),
1988            StringOrFloat::Float(i) => Ok(i),
1989        }
1990    }
1991}
1992
1993pub(crate) mod string_or_float_opt {
1994    use std::fmt;
1995
1996    use serde::{Deserialize, Deserializer, Serializer};
1997
1998    pub fn serialize<T, S>(value: &Option<T>, serializer: S) -> Result<S::Ok, S::Error>
1999    where
2000        T: fmt::Display,
2001        S: Serializer,
2002    {
2003        match value {
2004            Some(v) => crate::rest_model::string_or_float::serialize(v, serializer),
2005            None => serializer.serialize_none(),
2006        }
2007    }
2008
2009    pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<f64>, D::Error>
2010    where
2011        D: Deserializer<'de>,
2012    {
2013        #[derive(Deserialize)]
2014        #[serde(untagged)]
2015        enum StringOrFloat {
2016            String(String),
2017            Float(f64),
2018        }
2019
2020        Ok(Some(crate::rest_model::string_or_float::deserialize(deserializer)?))
2021    }
2022}
2023
2024pub mod string_or_u64 {
2025    use std::fmt;
2026
2027    use serde::{de, Deserialize, Deserializer, Serializer};
2028
2029    pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
2030    where
2031        T: fmt::Display,
2032        S: Serializer,
2033    {
2034        serializer.collect_str(value)
2035    }
2036
2037    pub fn deserialize<'de, D>(deserializer: D) -> Result<u64, D::Error>
2038    where
2039        D: Deserializer<'de>,
2040    {
2041        #[derive(Deserialize)]
2042        #[serde(untagged)]
2043        enum StringOrU64 {
2044            String(String),
2045            U64(u64),
2046        }
2047
2048        match StringOrU64::deserialize(deserializer)? {
2049            StringOrU64::String(s) => s.parse().map_err(de::Error::custom),
2050            StringOrU64::U64(i) => Ok(i),
2051        }
2052    }
2053}
2054
2055pub mod string_or_u64_opt {
2056    use std::fmt;
2057
2058    use serde::{de, Deserialize, Deserializer, Serializer};
2059
2060    pub fn serialize<T, S>(value: &Option<T>, serializer: S) -> Result<S::Ok, S::Error>
2061    where
2062        T: fmt::Display,
2063        S: Serializer,
2064    {
2065        match value {
2066            Some(v) => crate::rest_model::string_or_u64::serialize(v, serializer),
2067            None => serializer.serialize_none(),
2068        }
2069    }
2070
2071    pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<u64>, D::Error>
2072    where
2073        D: Deserializer<'de>,
2074    {
2075        #[derive(Deserialize)]
2076        #[serde(untagged)]
2077        enum StringOrU64 {
2078            String(String),
2079            U64(u64),
2080        }
2081
2082        match StringOrU64::deserialize(deserializer)? {
2083            StringOrU64::String(s) => s.parse().map_err(de::Error::custom).map(|v| Some(v)),
2084            StringOrU64::U64(i) => Ok(Some(i)),
2085        }
2086    }
2087}
2088
2089pub(crate) mod string_or_bool {
2090    use std::fmt;
2091
2092    use serde::{de, Deserialize, Deserializer, Serializer};
2093
2094    pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
2095    where
2096        T: fmt::Display,
2097        S: Serializer,
2098    {
2099        serializer.collect_str(value)
2100    }
2101
2102    pub fn deserialize<'de, D>(deserializer: D) -> Result<bool, D::Error>
2103    where
2104        D: Deserializer<'de>,
2105    {
2106        #[derive(Deserialize)]
2107        #[serde(untagged)]
2108        enum StringOrFloat {
2109            String(String),
2110            Bool(bool),
2111        }
2112
2113        match StringOrFloat::deserialize(deserializer)? {
2114            StringOrFloat::String(s) => s.parse().map_err(de::Error::custom),
2115            StringOrFloat::Bool(i) => Ok(i),
2116        }
2117    }
2118}
2119
2120#[cfg(test)]
2121mod test {
2122    use std::path::PathBuf;
2123
2124    use crate::rest_model::ExchangeInformation;
2125
2126    #[test]
2127    fn exchange_info_serde() {
2128        let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
2129        d.push("test_data/exchangeInfo.json");
2130        let fc = std::fs::read_to_string(d).unwrap();
2131        let result = serde_json::from_str::<ExchangeInformation>(&fc);
2132        assert!(result.is_ok(), "{result:?}");
2133    }
2134}