1use serde::{Deserialize, Serialize};
19
20#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
25#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
26pub enum BinanceProductType {
27 #[default]
29 Spot,
30 Margin,
32 UsdM,
34 CoinM,
36 Options,
38}
39
40impl BinanceProductType {
41 #[must_use]
43 pub const fn as_str(self) -> &'static str {
44 match self {
45 Self::Spot => "SPOT",
46 Self::Margin => "MARGIN",
47 Self::UsdM => "USD_M",
48 Self::CoinM => "COIN_M",
49 Self::Options => "OPTIONS",
50 }
51 }
52
53 #[must_use]
55 pub const fn suffix(self) -> &'static str {
56 match self {
57 Self::Spot => "-SPOT",
58 Self::Margin => "-MARGIN",
59 Self::UsdM => "-LINEAR",
60 Self::CoinM => "-INVERSE",
61 Self::Options => "-OPTION",
62 }
63 }
64
65 #[must_use]
67 pub const fn is_spot(self) -> bool {
68 matches!(self, Self::Spot | Self::Margin)
69 }
70
71 #[must_use]
73 pub const fn is_futures(self) -> bool {
74 matches!(self, Self::UsdM | Self::CoinM)
75 }
76
77 #[must_use]
79 pub const fn is_linear(self) -> bool {
80 matches!(self, Self::Spot | Self::Margin | Self::UsdM)
81 }
82
83 #[must_use]
85 pub const fn is_inverse(self) -> bool {
86 matches!(self, Self::CoinM)
87 }
88
89 #[must_use]
91 pub const fn is_options(self) -> bool {
92 matches!(self, Self::Options)
93 }
94}
95
96impl std::fmt::Display for BinanceProductType {
97 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
98 write!(f, "{}", self.as_str())
99 }
100}
101
102#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
104pub enum BinanceEnvironment {
105 #[default]
107 Mainnet,
108 Testnet,
110}
111
112impl BinanceEnvironment {
113 #[must_use]
115 pub const fn is_testnet(self) -> bool {
116 matches!(self, Self::Testnet)
117 }
118}
119
120#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
122#[serde(rename_all = "UPPERCASE")]
123pub enum BinanceSide {
124 Buy,
126 Sell,
128}
129
130#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
132#[serde(rename_all = "UPPERCASE")]
133pub enum BinancePositionSide {
134 Both,
136 Long,
138 Short,
140 #[serde(other)]
142 Unknown,
143}
144
145#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
147#[serde(rename_all = "lowercase")]
148pub enum BinanceMarginType {
149 Cross,
151 Isolated,
153 #[serde(other)]
155 Unknown,
156}
157
158#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
160#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
161pub enum BinanceWorkingType {
162 ContractPrice,
164 MarkPrice,
166 #[serde(other)]
168 Unknown,
169}
170
171#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
173#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
174pub enum BinanceOrderStatus {
175 New,
177 PartiallyFilled,
179 Filled,
181 Canceled,
183 PendingCancel,
185 Rejected,
187 Expired,
189 ExpiredInMatch,
191 #[serde(other)]
193 Unknown,
194}
195
196#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
198#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
199pub enum BinanceFuturesOrderType {
200 Limit,
202 Market,
204 Stop,
206 StopMarket,
208 TakeProfit,
210 TakeProfitMarket,
212 TrailingStopMarket,
214 Liquidation,
216 Adl,
218 #[serde(other)]
220 Unknown,
221}
222
223#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
225#[serde(rename_all = "UPPERCASE")]
226pub enum BinanceTimeInForce {
227 Gtc,
229 Ioc,
231 Fok,
233 Gtx,
235 Gtd,
237 #[serde(other)]
239 Unknown,
240}
241
242#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
244#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
245pub enum BinanceIncomeType {
246 Transfer,
248 WelcomeBonus,
250 RealizedPnl,
252 FundingFee,
254 Commission,
256 InsuranceClear,
258 ReferralKickback,
260 #[serde(other)]
262 Unknown,
263}
264
265#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
267#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
268pub enum BinancePriceMatch {
269 Opponent,
271 Opponent5,
273 Opponent10,
275 Opponent20,
277 Queue,
279 Queue5,
281 Queue10,
283 Queue20,
285 #[serde(other)]
287 Unknown,
288}
289
290#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
292#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
293pub enum BinanceSelfTradePreventionMode {
294 ExpireMaker,
296 ExpireTaker,
298 ExpireBoth,
300 #[serde(other)]
302 Unknown,
303}
304
305#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
307#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
308pub enum BinanceTradingStatus {
309 Trading,
311 PendingTrading,
313 PreTrading,
315 PostTrading,
317 EndOfDay,
319 Halt,
321 AuctionMatch,
323 Break,
325 #[serde(other)]
327 Unknown,
328}
329
330#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
332#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
333pub enum BinanceContractStatus {
334 Trading,
336 PendingTrading,
338 PreDelivering,
340 Delivering,
342 Delivered,
344 PreDelisting,
346 Delisting,
348 Down,
350 #[serde(other)]
352 Unknown,
353}
354
355#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
357#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
358pub enum BinanceFilterType {
359 PriceFilter,
361 PercentPrice,
363 LotSize,
365 MarketLotSize,
367 Notional,
369 MinNotional,
371 MaxNumOrders,
373 MaxNumAlgoOrders,
375 #[serde(other)]
377 Unknown,
378}
379
380impl std::fmt::Display for BinanceEnvironment {
381 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
382 match self {
383 Self::Mainnet => write!(f, "Mainnet"),
384 Self::Testnet => write!(f, "Testnet"),
385 }
386 }
387}
388
389#[cfg(test)]
390mod tests {
391 use rstest::rstest;
392
393 use super::*;
394
395 #[rstest]
396 fn test_product_type_as_str() {
397 assert_eq!(BinanceProductType::Spot.as_str(), "SPOT");
398 assert_eq!(BinanceProductType::Margin.as_str(), "MARGIN");
399 assert_eq!(BinanceProductType::UsdM.as_str(), "USD_M");
400 assert_eq!(BinanceProductType::CoinM.as_str(), "COIN_M");
401 assert_eq!(BinanceProductType::Options.as_str(), "OPTIONS");
402 }
403
404 #[rstest]
405 fn test_product_type_suffix() {
406 assert_eq!(BinanceProductType::Spot.suffix(), "-SPOT");
407 assert_eq!(BinanceProductType::Margin.suffix(), "-MARGIN");
408 assert_eq!(BinanceProductType::UsdM.suffix(), "-LINEAR");
409 assert_eq!(BinanceProductType::CoinM.suffix(), "-INVERSE");
410 assert_eq!(BinanceProductType::Options.suffix(), "-OPTION");
411 }
412
413 #[rstest]
414 fn test_product_type_predicates() {
415 assert!(BinanceProductType::Spot.is_spot());
416 assert!(BinanceProductType::Margin.is_spot());
417 assert!(!BinanceProductType::UsdM.is_spot());
418
419 assert!(BinanceProductType::UsdM.is_futures());
420 assert!(BinanceProductType::CoinM.is_futures());
421 assert!(!BinanceProductType::Spot.is_futures());
422
423 assert!(BinanceProductType::CoinM.is_inverse());
424 assert!(!BinanceProductType::UsdM.is_inverse());
425
426 assert!(BinanceProductType::Options.is_options());
427 assert!(!BinanceProductType::Spot.is_options());
428 }
429}