1use serde::{Deserialize, Serialize};
24use strum::{AsRefStr, Display, EnumIter, EnumString};
25
26#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
29#[serde(rename_all = "lowercase")]
30#[cfg_attr(
31 feature = "python",
32 pyo3::pyclass(
33 module = "nautilus_trader.core.nautilus_pyo3.derive",
34 eq,
35 eq_int,
36 frozen,
37 from_py_object,
38 rename_all = "SCREAMING_SNAKE_CASE"
39 )
40)]
41#[cfg_attr(
42 feature = "python",
43 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.adapters.derive")
44)]
45pub enum DeriveEnvironment {
46 #[default]
48 Mainnet,
49 Testnet,
51}
52
53impl DeriveEnvironment {
54 #[must_use]
55 pub const fn is_testnet(self) -> bool {
56 matches!(self, Self::Testnet)
57 }
58}
59
60#[derive(
64 Debug,
65 Clone,
66 Copy,
67 PartialEq,
68 Eq,
69 Hash,
70 Serialize,
71 Deserialize,
72 Display,
73 EnumString,
74 AsRefStr,
75 EnumIter,
76)]
77#[serde(rename_all = "lowercase")]
78#[strum(serialize_all = "lowercase")]
79pub enum DeriveInstrumentType {
80 Erc20,
82 Option,
84 Perp,
86}
87
88#[derive(
93 Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Display, EnumString, EnumIter,
94)]
95#[serde(rename_all = "lowercase")]
96#[strum(serialize_all = "lowercase")]
97pub enum DeriveAssetType {
98 Erc20,
100 Option,
102 Perp,
104}
105
106#[derive(
108 Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Display, EnumString, AsRefStr,
109)]
110#[serde(rename_all = "lowercase")]
111#[strum(serialize_all = "lowercase")]
112pub enum DeriveOrderSide {
113 Buy,
114 Sell,
115}
116
117#[derive(
119 Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Display, EnumString, AsRefStr,
120)]
121#[serde(rename_all = "lowercase")]
122#[strum(serialize_all = "lowercase")]
123pub enum DeriveOrderType {
124 Limit,
125 Market,
126}
127
128#[derive(
130 Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Display, EnumString, AsRefStr,
131)]
132#[serde(rename_all = "lowercase")]
133#[strum(serialize_all = "lowercase")]
134pub enum DeriveTriggerType {
135 Stoploss,
137 Takeprofit,
139}
140
141#[derive(
143 Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Display, EnumString, AsRefStr,
144)]
145#[serde(rename_all = "lowercase")]
146#[strum(serialize_all = "lowercase")]
147pub enum DeriveTriggerPriceType {
148 Mark,
150 Index,
152}
153
154#[derive(
157 Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Display, EnumString, AsRefStr,
158)]
159#[serde(rename_all = "snake_case")]
160#[strum(serialize_all = "snake_case")]
161pub enum DeriveOrderStatus {
162 Open,
164 Filled,
166 Rejected,
168 Cancelled,
170 Expired,
172 Untriggered,
174 AlgoActive,
176}
177
178#[derive(
180 Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Display, EnumString, AsRefStr,
181)]
182#[serde(rename_all = "snake_case")]
183#[strum(serialize_all = "snake_case")]
184pub enum DeriveTimeInForce {
185 Gtc,
187 PostOnly,
189 Fok,
191 Ioc,
193}
194
195#[derive(
197 Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Display, EnumString, AsRefStr,
198)]
199pub enum DeriveOptionKind {
200 #[serde(rename = "C")]
202 #[strum(serialize = "C")]
203 Call,
204 #[serde(rename = "P")]
206 #[strum(serialize = "P")]
207 Put,
208}
209
210#[derive(
216 Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Display, EnumString, AsRefStr,
217)]
218pub enum DeriveOrderCancelReason {
219 #[serde(rename = "")]
221 #[strum(serialize = "")]
222 Empty,
223 #[serde(rename = "user_request")]
225 #[strum(serialize = "user_request")]
226 UserRequest,
227 #[serde(rename = "mmp_trigger")]
229 #[strum(serialize = "mmp_trigger")]
230 MmpTrigger,
231 #[serde(rename = "insufficient_margin")]
233 #[strum(serialize = "insufficient_margin")]
234 InsufficientMargin,
235 #[serde(rename = "signed_max_fee_too_low")]
237 #[strum(serialize = "signed_max_fee_too_low")]
238 SignedMaxFeeTooLow,
239 #[serde(rename = "cancel_on_disconnect")]
241 #[strum(serialize = "cancel_on_disconnect")]
242 CancelOnDisconnect,
243 #[serde(rename = "ioc_or_market_partial_fill")]
245 #[strum(serialize = "ioc_or_market_partial_fill")]
246 IocOrMarketPartialFill,
247 #[serde(rename = "session_key_deregistered")]
249 #[strum(serialize = "session_key_deregistered")]
250 SessionKeyDeregistered,
251 #[serde(rename = "subaccount_withdrawn")]
253 #[strum(serialize = "subaccount_withdrawn")]
254 SubaccountWithdrawn,
255 #[serde(rename = "compliance")]
257 #[strum(serialize = "compliance")]
258 Compliance,
259 #[serde(rename = "trigger_failed")]
261 #[strum(serialize = "trigger_failed")]
262 TriggerFailed,
263 #[serde(rename = "validation_failed")]
265 #[strum(serialize = "validation_failed")]
266 ValidationFailed,
267 #[serde(rename = "algo_completed")]
269 #[strum(serialize = "algo_completed")]
270 AlgoCompleted,
271 #[serde(rename = "Post only order cannot cross the market")]
273 #[strum(serialize = "Post only order cannot cross the market")]
274 PostOnlyCrossMarket,
275}
276
277#[derive(
281 Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Display, EnumString, AsRefStr,
282)]
283pub enum DeriveRfqCancelReason {
284 #[serde(rename = "")]
286 #[strum(serialize = "")]
287 Empty,
288 #[serde(rename = "user_request")]
290 #[strum(serialize = "user_request")]
291 UserRequest,
292 #[serde(rename = "insufficient_margin")]
294 #[strum(serialize = "insufficient_margin")]
295 InsufficientMargin,
296 #[serde(rename = "signed_max_fee_too_low")]
298 #[strum(serialize = "signed_max_fee_too_low")]
299 SignedMaxFeeTooLow,
300 #[serde(rename = "mmp_trigger")]
302 #[strum(serialize = "mmp_trigger")]
303 MmpTrigger,
304 #[serde(rename = "cancel_on_disconnect")]
306 #[strum(serialize = "cancel_on_disconnect")]
307 CancelOnDisconnect,
308 #[serde(rename = "session_key_deregistered")]
310 #[strum(serialize = "session_key_deregistered")]
311 SessionKeyDeregistered,
312 #[serde(rename = "subaccount_withdrawn")]
314 #[strum(serialize = "subaccount_withdrawn")]
315 SubaccountWithdrawn,
316 #[serde(rename = "rfq_no_longer_open")]
318 #[strum(serialize = "rfq_no_longer_open")]
319 RfqNoLongerOpen,
320 #[serde(rename = "compliance")]
322 #[strum(serialize = "compliance")]
323 Compliance,
324}
325
326#[derive(
328 Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Display, EnumString, AsRefStr,
329)]
330#[serde(rename_all = "lowercase")]
331#[strum(serialize_all = "lowercase")]
332pub enum DeriveLiquidityRole {
333 Maker,
335 Taker,
337}
338
339#[derive(
342 Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Display, EnumString, AsRefStr,
343)]
344#[serde(rename_all = "lowercase")]
345#[strum(serialize_all = "lowercase")]
346pub enum DeriveTxStatus {
347 Requested,
349 Pending,
351 Settled,
353 Reverted,
355 Ignored,
357}
358
359#[derive(
363 Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Display, EnumString, AsRefStr,
364)]
365pub enum DeriveMarginType {
366 #[serde(rename = "SM")]
368 #[strum(serialize = "SM")]
369 Sm,
370 #[serde(rename = "PM")]
372 #[strum(serialize = "PM")]
373 Pm,
374 #[serde(rename = "PM2")]
376 #[strum(serialize = "PM2")]
377 Pm2,
378}
379
380#[derive(
382 Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Display, EnumString, AsRefStr,
383)]
384#[serde(rename_all = "lowercase")]
385#[strum(serialize_all = "lowercase")]
386pub enum DeriveAuctionType {
387 Solvent,
389 Insolvent,
391}
392
393#[derive(
395 Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Display, EnumString, AsRefStr,
396)]
397#[serde(rename_all = "lowercase")]
398#[strum(serialize_all = "lowercase")]
399pub enum DeriveAuctionState {
400 Ongoing,
402 Ended,
404}
405
406#[derive(
409 Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Display, EnumString, AsRefStr,
410)]
411#[serde(rename_all = "lowercase")]
412#[strum(serialize_all = "lowercase")]
413pub enum DeriveNotificationStatus {
414 Unseen,
416 Seen,
418 Hidden,
420}
421
422#[derive(
426 Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Display, EnumString, AsRefStr,
427)]
428#[serde(rename_all = "lowercase")]
429#[strum(serialize_all = "lowercase")]
430pub enum DeriveNotificationType {
431 Deposit,
433 Withdraw,
435 Transfer,
437 Trade,
439 Settlement,
441 Liquidation,
443 Types,
445}
446
447#[derive(
450 Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Display, EnumString, AsRefStr,
451)]
452#[serde(rename_all = "snake_case")]
453#[strum(serialize_all = "snake_case")]
454pub enum DeriveBalanceUpdateType {
455 Trade,
457 AssetDeposit,
459 AssetWithdrawal,
461 Transfer,
463 SubaccountDeposit,
465 SubaccountWithdrawal,
467 Liquidation,
469 OnchainDriftFix,
471 PerpSettlement,
473 OptionSettlement,
475 InterestAccrual,
477 OnchainRevert,
479 DoubleRevert,
481}
482
483#[derive(
485 Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Display, EnumString, AsRefStr,
486)]
487#[serde(rename_all = "lowercase")]
488#[strum(serialize_all = "lowercase")]
489pub enum DeriveComplianceStatus {
490 Enabled,
492 Disabled,
494}
495
496#[derive(
499 Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Display, EnumString, AsRefStr,
500)]
501pub enum DeriveOrderbookDepth {
502 #[serde(rename = "1")]
504 #[strum(serialize = "1")]
505 D1,
506 #[serde(rename = "10")]
508 #[strum(serialize = "10")]
509 D10,
510 #[serde(rename = "20")]
512 #[strum(serialize = "20")]
513 D20,
514 #[serde(rename = "100")]
516 #[strum(serialize = "100")]
517 D100,
518}
519
520#[derive(
522 Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Display, EnumString, AsRefStr,
523)]
524pub enum DeriveOrderbookGroup {
525 #[serde(rename = "1")]
527 #[strum(serialize = "1")]
528 G1,
529 #[serde(rename = "10")]
531 #[strum(serialize = "10")]
532 G10,
533 #[serde(rename = "100")]
535 #[strum(serialize = "100")]
536 G100,
537}
538
539#[derive(
542 Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Display, EnumString, AsRefStr,
543)]
544pub enum DeriveTickerInterval {
545 #[serde(rename = "100")]
547 #[strum(serialize = "100")]
548 Ms100,
549 #[serde(rename = "1000")]
551 #[strum(serialize = "1000")]
552 Ms1000,
553}
554
555#[cfg(test)]
556mod tests {
557 use std::str::FromStr;
558
559 use rstest::rstest;
560
561 use super::*;
562
563 #[rstest]
564 fn test_environment_default_is_mainnet() {
565 assert_eq!(DeriveEnvironment::default(), DeriveEnvironment::Mainnet);
566 assert!(!DeriveEnvironment::default().is_testnet());
567 assert!(DeriveEnvironment::Testnet.is_testnet());
568 }
569
570 #[rstest]
571 #[case(DeriveInstrumentType::Erc20, "erc20")]
572 #[case(DeriveInstrumentType::Option, "option")]
573 #[case(DeriveInstrumentType::Perp, "perp")]
574 fn test_instrument_type_display(#[case] variant: DeriveInstrumentType, #[case] expected: &str) {
575 assert_eq!(variant.to_string(), expected);
576 }
577
578 #[rstest]
579 #[case(DeriveTimeInForce::Gtc, "gtc")]
580 #[case(DeriveTimeInForce::PostOnly, "post_only")]
581 #[case(DeriveTimeInForce::Fok, "fok")]
582 #[case(DeriveTimeInForce::Ioc, "ioc")]
583 fn test_time_in_force_wire_strings(#[case] variant: DeriveTimeInForce, #[case] expected: &str) {
584 assert_eq!(variant.to_string(), expected);
585 assert_eq!(DeriveTimeInForce::from_str(expected).unwrap(), variant);
586 assert_eq!(
587 serde_json::to_string(&variant).unwrap(),
588 format!("\"{expected}\""),
589 );
590 }
591
592 #[rstest]
593 fn test_option_kind_serialization_uses_single_letter() {
594 assert_eq!(DeriveOptionKind::Call.to_string(), "C");
595 assert_eq!(DeriveOptionKind::Put.to_string(), "P");
596 assert_eq!(
597 DeriveOptionKind::from_str("C").unwrap(),
598 DeriveOptionKind::Call
599 );
600 assert_eq!(
601 DeriveOptionKind::from_str("P").unwrap(),
602 DeriveOptionKind::Put
603 );
604 }
605
606 #[rstest]
607 #[case(DeriveAssetType::Erc20, "erc20")]
608 #[case(DeriveAssetType::Option, "option")]
609 #[case(DeriveAssetType::Perp, "perp")]
610 fn test_asset_type_wire_strings(#[case] variant: DeriveAssetType, #[case] expected: &str) {
611 assert_eq!(variant.to_string(), expected);
612 assert_eq!(DeriveAssetType::from_str(expected).unwrap(), variant);
613 }
614
615 #[rstest]
616 #[case(DeriveOrderSide::Buy, "buy")]
617 #[case(DeriveOrderSide::Sell, "sell")]
618 fn test_order_side_wire_strings(#[case] variant: DeriveOrderSide, #[case] expected: &str) {
619 assert_eq!(variant.to_string(), expected);
620 assert_eq!(
621 serde_json::from_str::<DeriveOrderSide>(&format!("\"{expected}\"")).unwrap(),
622 variant
623 );
624 }
625
626 #[rstest]
627 #[case(DeriveOrderType::Limit, "limit")]
628 #[case(DeriveOrderType::Market, "market")]
629 fn test_order_type_wire_strings(#[case] variant: DeriveOrderType, #[case] expected: &str) {
630 assert_eq!(variant.to_string(), expected);
631 assert_eq!(DeriveOrderType::from_str(expected).unwrap(), variant);
632 }
633
634 #[rstest]
635 #[case(DeriveTriggerType::Stoploss, "stoploss")]
636 #[case(DeriveTriggerType::Takeprofit, "takeprofit")]
637 fn test_trigger_type_wire_strings(#[case] variant: DeriveTriggerType, #[case] expected: &str) {
638 assert_eq!(variant.to_string(), expected);
639 assert_eq!(DeriveTriggerType::from_str(expected).unwrap(), variant);
640 }
641
642 #[rstest]
643 #[case(DeriveTriggerPriceType::Mark, "mark")]
644 #[case(DeriveTriggerPriceType::Index, "index")]
645 fn test_trigger_price_type_wire_strings(
646 #[case] variant: DeriveTriggerPriceType,
647 #[case] expected: &str,
648 ) {
649 assert_eq!(variant.to_string(), expected);
650 assert_eq!(DeriveTriggerPriceType::from_str(expected).unwrap(), variant);
651 }
652
653 #[rstest]
654 #[case(DeriveOrderStatus::Open, "open")]
655 #[case(DeriveOrderStatus::Filled, "filled")]
656 #[case(DeriveOrderStatus::Rejected, "rejected")]
657 #[case(DeriveOrderStatus::Cancelled, "cancelled")]
658 #[case(DeriveOrderStatus::Expired, "expired")]
659 #[case(DeriveOrderStatus::Untriggered, "untriggered")]
660 #[case(DeriveOrderStatus::AlgoActive, "algo_active")]
661 fn test_order_status_wire_strings(#[case] variant: DeriveOrderStatus, #[case] expected: &str) {
662 assert_eq!(variant.to_string(), expected);
663 assert_eq!(DeriveOrderStatus::from_str(expected).unwrap(), variant);
664 }
665
666 #[rstest]
667 #[case(DeriveOrderCancelReason::Empty, "")]
668 #[case(DeriveOrderCancelReason::UserRequest, "user_request")]
669 #[case(DeriveOrderCancelReason::MmpTrigger, "mmp_trigger")]
670 #[case(DeriveOrderCancelReason::InsufficientMargin, "insufficient_margin")]
671 #[case(DeriveOrderCancelReason::SignedMaxFeeTooLow, "signed_max_fee_too_low")]
672 #[case(DeriveOrderCancelReason::CancelOnDisconnect, "cancel_on_disconnect")]
673 #[case(
674 DeriveOrderCancelReason::IocOrMarketPartialFill,
675 "ioc_or_market_partial_fill"
676 )]
677 #[case(
678 DeriveOrderCancelReason::SessionKeyDeregistered,
679 "session_key_deregistered"
680 )]
681 #[case(DeriveOrderCancelReason::SubaccountWithdrawn, "subaccount_withdrawn")]
682 #[case(DeriveOrderCancelReason::Compliance, "compliance")]
683 #[case(DeriveOrderCancelReason::TriggerFailed, "trigger_failed")]
684 #[case(DeriveOrderCancelReason::ValidationFailed, "validation_failed")]
685 #[case(DeriveOrderCancelReason::AlgoCompleted, "algo_completed")]
686 #[case(
687 DeriveOrderCancelReason::PostOnlyCrossMarket,
688 "Post only order cannot cross the market"
689 )]
690 fn test_order_cancel_reason_wire_strings(
691 #[case] variant: DeriveOrderCancelReason,
692 #[case] expected: &str,
693 ) {
694 assert_eq!(variant.to_string(), expected);
695 assert_eq!(
696 serde_json::from_str::<DeriveOrderCancelReason>(&format!("\"{expected}\"")).unwrap(),
697 variant
698 );
699 }
700
701 #[rstest]
702 #[case(DeriveRfqCancelReason::Empty, "")]
703 #[case(DeriveRfqCancelReason::UserRequest, "user_request")]
704 #[case(DeriveRfqCancelReason::InsufficientMargin, "insufficient_margin")]
705 #[case(DeriveRfqCancelReason::SignedMaxFeeTooLow, "signed_max_fee_too_low")]
706 #[case(DeriveRfqCancelReason::MmpTrigger, "mmp_trigger")]
707 #[case(DeriveRfqCancelReason::CancelOnDisconnect, "cancel_on_disconnect")]
708 #[case(
709 DeriveRfqCancelReason::SessionKeyDeregistered,
710 "session_key_deregistered"
711 )]
712 #[case(DeriveRfqCancelReason::SubaccountWithdrawn, "subaccount_withdrawn")]
713 #[case(DeriveRfqCancelReason::RfqNoLongerOpen, "rfq_no_longer_open")]
714 #[case(DeriveRfqCancelReason::Compliance, "compliance")]
715 fn test_rfq_cancel_reason_wire_strings(
716 #[case] variant: DeriveRfqCancelReason,
717 #[case] expected: &str,
718 ) {
719 assert_eq!(variant.to_string(), expected);
720 assert_eq!(
721 serde_json::from_str::<DeriveRfqCancelReason>(&format!("\"{expected}\"")).unwrap(),
722 variant
723 );
724 }
725
726 #[rstest]
727 fn test_order_cancel_reason_empty_string_round_trips() {
728 let json = serde_json::to_string(&DeriveOrderCancelReason::Empty).unwrap();
729 assert_eq!(json, "\"\"");
730 let parsed: DeriveOrderCancelReason = serde_json::from_str("\"\"").unwrap();
731 assert_eq!(parsed, DeriveOrderCancelReason::Empty);
732 }
733
734 #[rstest]
735 #[case(DeriveLiquidityRole::Maker, "maker")]
736 #[case(DeriveLiquidityRole::Taker, "taker")]
737 fn test_liquidity_role_wire_strings(
738 #[case] variant: DeriveLiquidityRole,
739 #[case] expected: &str,
740 ) {
741 assert_eq!(variant.to_string(), expected);
742 assert_eq!(DeriveLiquidityRole::from_str(expected).unwrap(), variant);
743 }
744
745 #[rstest]
746 #[case(DeriveTxStatus::Requested, "requested")]
747 #[case(DeriveTxStatus::Pending, "pending")]
748 #[case(DeriveTxStatus::Settled, "settled")]
749 #[case(DeriveTxStatus::Reverted, "reverted")]
750 #[case(DeriveTxStatus::Ignored, "ignored")]
751 fn test_tx_status_wire_strings(#[case] variant: DeriveTxStatus, #[case] expected: &str) {
752 assert_eq!(variant.to_string(), expected);
753 assert_eq!(DeriveTxStatus::from_str(expected).unwrap(), variant);
754 }
755
756 #[rstest]
757 #[case(DeriveMarginType::Sm, "SM")]
758 #[case(DeriveMarginType::Pm, "PM")]
759 #[case(DeriveMarginType::Pm2, "PM2")]
760 fn test_margin_type_wire_strings(#[case] variant: DeriveMarginType, #[case] expected: &str) {
761 assert_eq!(variant.to_string(), expected);
762 assert_eq!(DeriveMarginType::from_str(expected).unwrap(), variant);
763 }
764
765 #[rstest]
766 #[case(DeriveAuctionType::Solvent, "solvent")]
767 #[case(DeriveAuctionType::Insolvent, "insolvent")]
768 fn test_auction_type_wire_strings(#[case] variant: DeriveAuctionType, #[case] expected: &str) {
769 assert_eq!(variant.to_string(), expected);
770 assert_eq!(DeriveAuctionType::from_str(expected).unwrap(), variant);
771 }
772
773 #[rstest]
774 #[case(DeriveAuctionState::Ongoing, "ongoing")]
775 #[case(DeriveAuctionState::Ended, "ended")]
776 fn test_auction_state_wire_strings(
777 #[case] variant: DeriveAuctionState,
778 #[case] expected: &str,
779 ) {
780 assert_eq!(variant.to_string(), expected);
781 assert_eq!(DeriveAuctionState::from_str(expected).unwrap(), variant);
782 }
783
784 #[rstest]
785 #[case(DeriveNotificationStatus::Unseen, "unseen")]
786 #[case(DeriveNotificationStatus::Seen, "seen")]
787 #[case(DeriveNotificationStatus::Hidden, "hidden")]
788 fn test_notification_status_wire_strings(
789 #[case] variant: DeriveNotificationStatus,
790 #[case] expected: &str,
791 ) {
792 assert_eq!(variant.to_string(), expected);
793 assert_eq!(
794 DeriveNotificationStatus::from_str(expected).unwrap(),
795 variant
796 );
797 }
798
799 #[rstest]
800 #[case(DeriveNotificationType::Deposit, "deposit")]
801 #[case(DeriveNotificationType::Withdraw, "withdraw")]
802 #[case(DeriveNotificationType::Transfer, "transfer")]
803 #[case(DeriveNotificationType::Trade, "trade")]
804 #[case(DeriveNotificationType::Settlement, "settlement")]
805 #[case(DeriveNotificationType::Liquidation, "liquidation")]
806 #[case(DeriveNotificationType::Types, "types")]
807 fn test_notification_type_wire_strings(
808 #[case] variant: DeriveNotificationType,
809 #[case] expected: &str,
810 ) {
811 assert_eq!(variant.to_string(), expected);
812 assert_eq!(DeriveNotificationType::from_str(expected).unwrap(), variant);
813 }
814
815 #[rstest]
816 #[case(DeriveBalanceUpdateType::Trade, "trade")]
817 #[case(DeriveBalanceUpdateType::AssetDeposit, "asset_deposit")]
818 #[case(DeriveBalanceUpdateType::AssetWithdrawal, "asset_withdrawal")]
819 #[case(DeriveBalanceUpdateType::Transfer, "transfer")]
820 #[case(DeriveBalanceUpdateType::SubaccountDeposit, "subaccount_deposit")]
821 #[case(DeriveBalanceUpdateType::SubaccountWithdrawal, "subaccount_withdrawal")]
822 #[case(DeriveBalanceUpdateType::Liquidation, "liquidation")]
823 #[case(DeriveBalanceUpdateType::OnchainDriftFix, "onchain_drift_fix")]
824 #[case(DeriveBalanceUpdateType::PerpSettlement, "perp_settlement")]
825 #[case(DeriveBalanceUpdateType::OptionSettlement, "option_settlement")]
826 #[case(DeriveBalanceUpdateType::InterestAccrual, "interest_accrual")]
827 #[case(DeriveBalanceUpdateType::OnchainRevert, "onchain_revert")]
828 #[case(DeriveBalanceUpdateType::DoubleRevert, "double_revert")]
829 fn test_balance_update_type_wire_strings(
830 #[case] variant: DeriveBalanceUpdateType,
831 #[case] expected: &str,
832 ) {
833 assert_eq!(variant.to_string(), expected);
834 assert_eq!(
835 DeriveBalanceUpdateType::from_str(expected).unwrap(),
836 variant
837 );
838 }
839
840 #[rstest]
841 #[case(DeriveComplianceStatus::Enabled, "enabled")]
842 #[case(DeriveComplianceStatus::Disabled, "disabled")]
843 fn test_compliance_status_wire_strings(
844 #[case] variant: DeriveComplianceStatus,
845 #[case] expected: &str,
846 ) {
847 assert_eq!(variant.to_string(), expected);
848 assert_eq!(DeriveComplianceStatus::from_str(expected).unwrap(), variant);
849 }
850
851 #[rstest]
852 #[case(DeriveOrderbookDepth::D1, "1")]
853 #[case(DeriveOrderbookDepth::D10, "10")]
854 #[case(DeriveOrderbookDepth::D20, "20")]
855 #[case(DeriveOrderbookDepth::D100, "100")]
856 fn test_orderbook_depth_wire_strings(
857 #[case] variant: DeriveOrderbookDepth,
858 #[case] expected: &str,
859 ) {
860 assert_eq!(variant.to_string(), expected);
861 assert_eq!(DeriveOrderbookDepth::from_str(expected).unwrap(), variant);
862 }
863
864 #[rstest]
865 #[case(DeriveOrderbookGroup::G1, "1")]
866 #[case(DeriveOrderbookGroup::G10, "10")]
867 #[case(DeriveOrderbookGroup::G100, "100")]
868 fn test_orderbook_group_wire_strings(
869 #[case] variant: DeriveOrderbookGroup,
870 #[case] expected: &str,
871 ) {
872 assert_eq!(variant.to_string(), expected);
873 assert_eq!(DeriveOrderbookGroup::from_str(expected).unwrap(), variant);
874 }
875
876 #[rstest]
877 #[case(DeriveTickerInterval::Ms100, "100")]
878 #[case(DeriveTickerInterval::Ms1000, "1000")]
879 fn test_ticker_interval_wire_strings(
880 #[case] variant: DeriveTickerInterval,
881 #[case] expected: &str,
882 ) {
883 assert_eq!(variant.to_string(), expected);
884 assert_eq!(DeriveTickerInterval::from_str(expected).unwrap(), variant);
885 }
886}