1use std::{ffi::c_char, str::FromStr};
17
18use nautilus_core::ffi::{
19 abort_on_panic,
20 string::{cstr_as_str, str_to_cstr},
21};
22use strum::{AsRefStr, Display, EnumString};
23
24use crate::enums::{
25 AccountType, AggregationSource, AggressorSide, AssetClass, BarAggregation, BookAction,
26 BookType, ContingencyType, CurrencyType, InstrumentClass, InstrumentCloseType, LiquiditySide,
27 MarketStatus, MarketStatusAction, OmsType, OptionKind, OrderSide, OrderStatus, OrderType,
28 OtoTriggerMode, PositionAdjustmentType, PositionSide, PriceType, RecordFlag, TimeInForce,
29 TradingState, TrailingOffsetType, TriggerType,
30};
31
32#[repr(C)]
36#[derive(Copy, Clone, Debug, Default, Display, Hash, PartialEq, Eq, AsRefStr, EnumString)]
37#[strum(ascii_case_insensitive)]
38#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
39pub enum ContingencyTypeOptional {
40 #[default]
44 NoContingency = 0,
45 Oco = 1,
47 Oto = 2,
49 Ouo = 3,
51}
52
53impl ContingencyTypeOptional {
54 #[must_use]
55 pub const fn as_option(self) -> Option<ContingencyType> {
56 match self {
57 Self::NoContingency => None,
58 Self::Oco => Some(ContingencyType::Oco),
59 Self::Oto => Some(ContingencyType::Oto),
60 Self::Ouo => Some(ContingencyType::Ouo),
61 }
62 }
63}
64
65impl From<Option<ContingencyType>> for ContingencyTypeOptional {
66 fn from(value: Option<ContingencyType>) -> Self {
67 match value {
68 None => Self::NoContingency,
69 Some(ContingencyType::Oco) => Self::Oco,
70 Some(ContingencyType::Oto) => Self::Oto,
71 Some(ContingencyType::Ouo) => Self::Ouo,
72 }
73 }
74}
75
76#[repr(C)]
80#[derive(Copy, Clone, Debug, Default, Display, Hash, PartialEq, Eq, AsRefStr, EnumString)]
81#[strum(ascii_case_insensitive)]
82#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
83pub enum OrderSideOptional {
84 #[default]
88 NoOrderSide = 0,
89 Buy = 1,
91 Sell = 2,
93}
94
95impl OrderSideOptional {
96 #[must_use]
97 pub const fn as_option(self) -> Option<OrderSide> {
98 match self {
99 Self::NoOrderSide => None,
100 Self::Buy => Some(OrderSide::Buy),
101 Self::Sell => Some(OrderSide::Sell),
102 }
103 }
104}
105
106impl From<Option<OrderSide>> for OrderSideOptional {
107 fn from(value: Option<OrderSide>) -> Self {
108 match value {
109 None => Self::NoOrderSide,
110 Some(OrderSide::Buy) => Self::Buy,
111 Some(OrderSide::Sell) => Self::Sell,
112 }
113 }
114}
115
116#[repr(C)]
120#[derive(Copy, Clone, Debug, Default, Display, Hash, PartialEq, Eq, AsRefStr, EnumString)]
121#[strum(ascii_case_insensitive)]
122#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
123pub enum PositionSideOptional {
124 #[default]
128 NoPositionSide = 0,
129 Flat = 1,
131 Long = 2,
133 Short = 3,
135}
136
137impl PositionSideOptional {
138 #[must_use]
139 pub const fn as_option(self) -> Option<PositionSide> {
140 match self {
141 Self::NoPositionSide => None,
142 Self::Flat => Some(PositionSide::Flat),
143 Self::Long => Some(PositionSide::Long),
144 Self::Short => Some(PositionSide::Short),
145 }
146 }
147}
148
149impl From<Option<PositionSide>> for PositionSideOptional {
150 fn from(value: Option<PositionSide>) -> Self {
151 match value {
152 None => Self::NoPositionSide,
153 Some(PositionSide::Flat) => Self::Flat,
154 Some(PositionSide::Long) => Self::Long,
155 Some(PositionSide::Short) => Self::Short,
156 }
157 }
158}
159
160#[repr(C)]
164#[derive(Copy, Clone, Debug, Default, Display, Hash, PartialEq, Eq, AsRefStr, EnumString)]
165#[strum(ascii_case_insensitive)]
166#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
167pub enum TrailingOffsetTypeOptional {
168 #[default]
172 NoTrailingOffset = 0,
173 Price = 1,
175 BasisPoints = 2,
177 Ticks = 3,
179 PriceTier = 4,
181}
182
183impl TrailingOffsetTypeOptional {
184 #[must_use]
185 pub const fn as_option(self) -> Option<TrailingOffsetType> {
186 match self {
187 Self::NoTrailingOffset => None,
188 Self::Price => Some(TrailingOffsetType::Price),
189 Self::BasisPoints => Some(TrailingOffsetType::BasisPoints),
190 Self::Ticks => Some(TrailingOffsetType::Ticks),
191 Self::PriceTier => Some(TrailingOffsetType::PriceTier),
192 }
193 }
194}
195
196impl From<Option<TrailingOffsetType>> for TrailingOffsetTypeOptional {
197 fn from(value: Option<TrailingOffsetType>) -> Self {
198 match value {
199 None => Self::NoTrailingOffset,
200 Some(TrailingOffsetType::Price) => Self::Price,
201 Some(TrailingOffsetType::BasisPoints) => Self::BasisPoints,
202 Some(TrailingOffsetType::Ticks) => Self::Ticks,
203 Some(TrailingOffsetType::PriceTier) => Self::PriceTier,
204 }
205 }
206}
207
208#[repr(C)]
212#[derive(Copy, Clone, Debug, Default, Display, Hash, PartialEq, Eq, AsRefStr, EnumString)]
213#[strum(ascii_case_insensitive)]
214#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
215pub enum TriggerTypeOptional {
216 #[default]
220 NoTrigger = 0,
221 Default = 1,
223 LastPrice = 2,
225 MarkPrice = 3,
227 IndexPrice = 4,
229 BidAsk = 5,
231 DoubleLast = 6,
233 DoubleBidAsk = 7,
235 LastOrBidAsk = 8,
237 MidPoint = 9,
239}
240
241impl TriggerTypeOptional {
242 #[must_use]
243 pub const fn as_option(self) -> Option<TriggerType> {
244 match self {
245 Self::NoTrigger => None,
246 Self::Default => Some(TriggerType::Default),
247 Self::LastPrice => Some(TriggerType::LastPrice),
248 Self::MarkPrice => Some(TriggerType::MarkPrice),
249 Self::IndexPrice => Some(TriggerType::IndexPrice),
250 Self::BidAsk => Some(TriggerType::BidAsk),
251 Self::DoubleLast => Some(TriggerType::DoubleLast),
252 Self::DoubleBidAsk => Some(TriggerType::DoubleBidAsk),
253 Self::LastOrBidAsk => Some(TriggerType::LastOrBidAsk),
254 Self::MidPoint => Some(TriggerType::MidPoint),
255 }
256 }
257}
258
259impl From<Option<TriggerType>> for TriggerTypeOptional {
260 fn from(value: Option<TriggerType>) -> Self {
261 match value {
262 None => Self::NoTrigger,
263 Some(TriggerType::Default) => Self::Default,
264 Some(TriggerType::LastPrice) => Self::LastPrice,
265 Some(TriggerType::MarkPrice) => Self::MarkPrice,
266 Some(TriggerType::IndexPrice) => Self::IndexPrice,
267 Some(TriggerType::BidAsk) => Self::BidAsk,
268 Some(TriggerType::DoubleLast) => Self::DoubleLast,
269 Some(TriggerType::DoubleBidAsk) => Self::DoubleBidAsk,
270 Some(TriggerType::LastOrBidAsk) => Self::LastOrBidAsk,
271 Some(TriggerType::MidPoint) => Self::MidPoint,
272 }
273 }
274}
275
276#[unsafe(no_mangle)]
277pub extern "C" fn account_type_to_cstr(value: AccountType) -> *const c_char {
278 str_to_cstr(value.as_ref())
279}
280
281#[unsafe(no_mangle)]
291pub unsafe extern "C" fn account_type_from_cstr(ptr: *const c_char) -> AccountType {
292 abort_on_panic(|| {
293 let value = unsafe { cstr_as_str(ptr) };
294 AccountType::from_str(value)
295 .unwrap_or_else(|_| panic!("invalid `AccountType` enum string value, was '{value}'"))
296 })
297}
298
299#[unsafe(no_mangle)]
300pub extern "C" fn aggregation_source_to_cstr(value: AggregationSource) -> *const c_char {
301 str_to_cstr(value.as_ref())
302}
303
304#[unsafe(no_mangle)]
314pub unsafe extern "C" fn aggregation_source_from_cstr(ptr: *const c_char) -> AggregationSource {
315 abort_on_panic(|| {
316 let value = unsafe { cstr_as_str(ptr) };
317 AggregationSource::from_str(value).unwrap_or_else(|_| {
318 panic!("invalid `AggregationSource` enum string value, was '{value}'")
319 })
320 })
321}
322
323#[unsafe(no_mangle)]
324pub extern "C" fn aggressor_side_to_cstr(value: AggressorSide) -> *const c_char {
325 str_to_cstr(value.as_ref())
326}
327
328#[unsafe(no_mangle)]
338pub unsafe extern "C" fn aggressor_side_from_cstr(ptr: *const c_char) -> AggressorSide {
339 abort_on_panic(|| {
340 let value = unsafe { cstr_as_str(ptr) };
341 AggressorSide::from_str(value)
342 .unwrap_or_else(|_| panic!("invalid `AggressorSide` enum string value, was '{value}'"))
343 })
344}
345
346#[unsafe(no_mangle)]
347pub extern "C" fn asset_class_to_cstr(value: AssetClass) -> *const c_char {
348 str_to_cstr(value.as_ref())
349}
350
351#[unsafe(no_mangle)]
361pub unsafe extern "C" fn asset_class_from_cstr(ptr: *const c_char) -> AssetClass {
362 abort_on_panic(|| {
363 let value = unsafe { cstr_as_str(ptr) };
364 AssetClass::from_str(value)
365 .unwrap_or_else(|_| panic!("invalid `AssetClass` enum string value, was '{value}'"))
366 })
367}
368
369#[unsafe(no_mangle)]
370pub extern "C" fn instrument_class_to_cstr(value: InstrumentClass) -> *const c_char {
371 str_to_cstr(value.as_ref())
372}
373
374#[unsafe(no_mangle)]
384pub unsafe extern "C" fn instrument_class_from_cstr(ptr: *const c_char) -> InstrumentClass {
385 abort_on_panic(|| {
386 let value = unsafe { cstr_as_str(ptr) };
387 InstrumentClass::from_str(value).unwrap_or_else(|_| {
388 panic!("invalid `InstrumentClass` enum string value, was '{value}'")
389 })
390 })
391}
392
393#[unsafe(no_mangle)]
394pub extern "C" fn bar_aggregation_to_cstr(value: BarAggregation) -> *const c_char {
395 str_to_cstr(value.as_ref())
396}
397
398#[unsafe(no_mangle)]
408pub unsafe extern "C" fn bar_aggregation_from_cstr(ptr: *const c_char) -> BarAggregation {
409 abort_on_panic(|| {
410 let value = unsafe { cstr_as_str(ptr) };
411 BarAggregation::from_str(value)
412 .unwrap_or_else(|_| panic!("invalid `BarAggregation` enum string value, was '{value}'"))
413 })
414}
415
416#[unsafe(no_mangle)]
417pub extern "C" fn book_action_to_cstr(value: BookAction) -> *const c_char {
418 str_to_cstr(value.as_ref())
419}
420
421#[unsafe(no_mangle)]
431pub unsafe extern "C" fn book_action_from_cstr(ptr: *const c_char) -> BookAction {
432 abort_on_panic(|| {
433 let value = unsafe { cstr_as_str(ptr) };
434 BookAction::from_str(value)
435 .unwrap_or_else(|_| panic!("invalid `BookAction` enum string value, was '{value}'"))
436 })
437}
438
439#[unsafe(no_mangle)]
440pub extern "C" fn book_type_to_cstr(value: BookType) -> *const c_char {
441 str_to_cstr(value.as_ref())
442}
443
444#[unsafe(no_mangle)]
454pub unsafe extern "C" fn book_type_from_cstr(ptr: *const c_char) -> BookType {
455 abort_on_panic(|| {
456 let value = unsafe { cstr_as_str(ptr) };
457 BookType::from_str(value)
458 .unwrap_or_else(|_| panic!("invalid `BookType` enum string value, was '{value}'"))
459 })
460}
461
462#[unsafe(no_mangle)]
463pub extern "C" fn contingency_type_to_cstr(value: ContingencyTypeOptional) -> *const c_char {
464 str_to_cstr(value.as_ref())
465}
466
467#[unsafe(no_mangle)]
477pub unsafe extern "C" fn contingency_type_from_cstr(ptr: *const c_char) -> ContingencyTypeOptional {
478 abort_on_panic(|| {
479 let value = unsafe { cstr_as_str(ptr) };
480 ContingencyTypeOptional::from_str(value).unwrap_or_else(|_| {
481 panic!("invalid `ContingencyTypeOptional` enum string value, was '{value}'")
482 })
483 })
484}
485
486#[unsafe(no_mangle)]
487pub extern "C" fn currency_type_to_cstr(value: CurrencyType) -> *const c_char {
488 str_to_cstr(value.as_ref())
489}
490
491#[unsafe(no_mangle)]
501pub unsafe extern "C" fn currency_type_from_cstr(ptr: *const c_char) -> CurrencyType {
502 abort_on_panic(|| {
503 let value = unsafe { cstr_as_str(ptr) };
504 CurrencyType::from_str(value)
505 .unwrap_or_else(|_| panic!("invalid `CurrencyType` enum string value, was '{value}'"))
506 })
507}
508
509#[unsafe(no_mangle)]
519pub unsafe extern "C" fn instrument_close_type_from_cstr(
520 ptr: *const c_char,
521) -> InstrumentCloseType {
522 abort_on_panic(|| {
523 let value = unsafe { cstr_as_str(ptr) };
524 InstrumentCloseType::from_str(value).unwrap_or_else(|_| {
525 panic!("invalid `InstrumentCloseType` enum string value, was '{value}'")
526 })
527 })
528}
529
530#[unsafe(no_mangle)]
531pub extern "C" fn instrument_close_type_to_cstr(value: InstrumentCloseType) -> *const c_char {
532 str_to_cstr(value.as_ref())
533}
534
535#[unsafe(no_mangle)]
536pub extern "C" fn liquidity_side_to_cstr(value: LiquiditySide) -> *const c_char {
537 str_to_cstr(value.as_ref())
538}
539
540#[unsafe(no_mangle)]
550pub unsafe extern "C" fn liquidity_side_from_cstr(ptr: *const c_char) -> LiquiditySide {
551 abort_on_panic(|| {
552 let value = unsafe { cstr_as_str(ptr) };
553 LiquiditySide::from_str(value)
554 .unwrap_or_else(|_| panic!("invalid `LiquiditySide` enum string value, was '{value}'"))
555 })
556}
557
558#[unsafe(no_mangle)]
559pub extern "C" fn market_status_to_cstr(value: MarketStatus) -> *const c_char {
560 str_to_cstr(value.as_ref())
561}
562
563#[unsafe(no_mangle)]
573pub unsafe extern "C" fn market_status_from_cstr(ptr: *const c_char) -> MarketStatus {
574 abort_on_panic(|| {
575 let value = unsafe { cstr_as_str(ptr) };
576 MarketStatus::from_str(value)
577 .unwrap_or_else(|_| panic!("invalid `MarketStatus` enum string value, was '{value}'"))
578 })
579}
580
581#[unsafe(no_mangle)]
582pub extern "C" fn market_status_action_to_cstr(value: MarketStatusAction) -> *const c_char {
583 str_to_cstr(value.as_ref())
584}
585
586#[unsafe(no_mangle)]
596pub unsafe extern "C" fn market_status_action_from_cstr(ptr: *const c_char) -> MarketStatusAction {
597 abort_on_panic(|| {
598 let value = unsafe { cstr_as_str(ptr) };
599 MarketStatusAction::from_str(value).unwrap_or_else(|_| {
600 panic!("invalid `MarketStatusAction` enum string value, was '{value}'")
601 })
602 })
603}
604
605#[unsafe(no_mangle)]
606pub extern "C" fn oms_type_to_cstr(value: OmsType) -> *const c_char {
607 str_to_cstr(value.as_ref())
608}
609
610#[unsafe(no_mangle)]
620pub unsafe extern "C" fn oms_type_from_cstr(ptr: *const c_char) -> OmsType {
621 abort_on_panic(|| {
622 let value = unsafe { cstr_as_str(ptr) };
623 OmsType::from_str(value)
624 .unwrap_or_else(|_| panic!("invalid `OmsType` enum string value, was '{value}'"))
625 })
626}
627
628#[unsafe(no_mangle)]
629pub extern "C" fn option_kind_to_cstr(value: OptionKind) -> *const c_char {
630 str_to_cstr(value.as_ref())
631}
632
633#[unsafe(no_mangle)]
643pub unsafe extern "C" fn option_kind_from_cstr(ptr: *const c_char) -> OptionKind {
644 abort_on_panic(|| {
645 let value = unsafe { cstr_as_str(ptr) };
646 OptionKind::from_str(value)
647 .unwrap_or_else(|_| panic!("invalid `OptionKind` enum string value, was '{value}'"))
648 })
649}
650
651#[unsafe(no_mangle)]
652pub extern "C" fn oto_trigger_mode_to_cstr(value: OtoTriggerMode) -> *const c_char {
653 str_to_cstr(value.as_ref())
654}
655
656#[unsafe(no_mangle)]
666pub unsafe extern "C" fn oto_trigger_mode_from_cstr(ptr: *const c_char) -> OtoTriggerMode {
667 abort_on_panic(|| {
668 let value = unsafe { cstr_as_str(ptr) };
669 OtoTriggerMode::from_str(value)
670 .unwrap_or_else(|_| panic!("invalid `OtoTriggerMode` enum string value, was '{value}'"))
671 })
672}
673
674#[unsafe(no_mangle)]
675pub extern "C" fn order_side_to_cstr(value: OrderSideOptional) -> *const c_char {
676 str_to_cstr(value.as_ref())
677}
678
679#[unsafe(no_mangle)]
689pub unsafe extern "C" fn order_side_from_cstr(ptr: *const c_char) -> OrderSideOptional {
690 abort_on_panic(|| {
691 let value = unsafe { cstr_as_str(ptr) };
692 OrderSideOptional::from_str(value).unwrap_or_else(|_| {
693 panic!("invalid `OrderSideOptional` enum string value, was '{value}'")
694 })
695 })
696}
697
698#[unsafe(no_mangle)]
699pub extern "C" fn order_status_to_cstr(value: OrderStatus) -> *const c_char {
700 str_to_cstr(value.as_ref())
701}
702
703#[unsafe(no_mangle)]
713pub unsafe extern "C" fn order_status_from_cstr(ptr: *const c_char) -> OrderStatus {
714 abort_on_panic(|| {
715 let value = unsafe { cstr_as_str(ptr) };
716 OrderStatus::from_str(value)
717 .unwrap_or_else(|_| panic!("invalid `OrderStatus` enum string value, was '{value}'"))
718 })
719}
720
721#[unsafe(no_mangle)]
722pub extern "C" fn order_type_to_cstr(value: OrderType) -> *const c_char {
723 str_to_cstr(value.as_ref())
724}
725
726#[unsafe(no_mangle)]
736pub unsafe extern "C" fn order_type_from_cstr(ptr: *const c_char) -> OrderType {
737 abort_on_panic(|| {
738 let value = unsafe { cstr_as_str(ptr) };
739 OrderType::from_str(value)
740 .unwrap_or_else(|_| panic!("invalid `OrderType` enum string value, was '{value}'"))
741 })
742}
743
744#[unsafe(no_mangle)]
745pub extern "C" fn position_side_to_cstr(value: PositionSideOptional) -> *const c_char {
746 str_to_cstr(value.as_ref())
747}
748
749#[unsafe(no_mangle)]
759pub unsafe extern "C" fn position_side_from_cstr(ptr: *const c_char) -> PositionSideOptional {
760 abort_on_panic(|| {
761 let value = unsafe { cstr_as_str(ptr) };
762 PositionSideOptional::from_str(value).unwrap_or_else(|_| {
763 panic!("invalid `PositionSideOptional` enum string value, was '{value}'")
764 })
765 })
766}
767
768#[unsafe(no_mangle)]
769pub extern "C" fn position_adjustment_type_to_cstr(value: PositionAdjustmentType) -> *const c_char {
770 str_to_cstr(value.as_ref())
771}
772
773#[unsafe(no_mangle)]
783pub unsafe extern "C" fn position_adjustment_type_from_cstr(
784 ptr: *const c_char,
785) -> PositionAdjustmentType {
786 abort_on_panic(|| {
787 let value = unsafe { cstr_as_str(ptr) };
788 PositionAdjustmentType::from_str(value).unwrap_or_else(|_| {
789 panic!("invalid `PositionAdjustmentType` enum string value, was '{value}'")
790 })
791 })
792}
793
794#[unsafe(no_mangle)]
795pub extern "C" fn price_type_to_cstr(value: PriceType) -> *const c_char {
796 str_to_cstr(value.as_ref())
797}
798
799#[unsafe(no_mangle)]
809pub unsafe extern "C" fn price_type_from_cstr(ptr: *const c_char) -> PriceType {
810 abort_on_panic(|| {
811 let value = unsafe { cstr_as_str(ptr) };
812 PriceType::from_str(value)
813 .unwrap_or_else(|_| panic!("invalid `PriceType` enum string value, was '{value}'"))
814 })
815}
816
817#[unsafe(no_mangle)]
818pub extern "C" fn record_flag_to_cstr(value: RecordFlag) -> *const c_char {
819 str_to_cstr(value.as_ref())
820}
821
822#[unsafe(no_mangle)]
832pub unsafe extern "C" fn record_flag_from_cstr(ptr: *const c_char) -> RecordFlag {
833 abort_on_panic(|| {
834 let value = unsafe { cstr_as_str(ptr) };
835 RecordFlag::from_str(value)
836 .unwrap_or_else(|_| panic!("invalid `RecordFlag` enum string value, was '{value}'"))
837 })
838}
839
840#[unsafe(no_mangle)]
841pub extern "C" fn time_in_force_to_cstr(value: TimeInForce) -> *const c_char {
842 str_to_cstr(value.as_ref())
843}
844
845#[unsafe(no_mangle)]
855pub unsafe extern "C" fn time_in_force_from_cstr(ptr: *const c_char) -> TimeInForce {
856 abort_on_panic(|| {
857 let value = unsafe { cstr_as_str(ptr) };
858 TimeInForce::from_str(value)
859 .unwrap_or_else(|_| panic!("invalid `TimeInForce` enum string value, was '{value}'"))
860 })
861}
862
863#[unsafe(no_mangle)]
864pub extern "C" fn trading_state_to_cstr(value: TradingState) -> *const c_char {
865 str_to_cstr(value.as_ref())
866}
867
868#[unsafe(no_mangle)]
878pub unsafe extern "C" fn trading_state_from_cstr(ptr: *const c_char) -> TradingState {
879 abort_on_panic(|| {
880 let value = unsafe { cstr_as_str(ptr) };
881 TradingState::from_str(value)
882 .unwrap_or_else(|_| panic!("invalid `TradingState` enum string value, was '{value}'"))
883 })
884}
885
886#[unsafe(no_mangle)]
887pub extern "C" fn trailing_offset_type_to_cstr(value: TrailingOffsetTypeOptional) -> *const c_char {
888 str_to_cstr(value.as_ref())
889}
890
891#[unsafe(no_mangle)]
901pub unsafe extern "C" fn trailing_offset_type_from_cstr(
902 ptr: *const c_char,
903) -> TrailingOffsetTypeOptional {
904 abort_on_panic(|| {
905 let value = unsafe { cstr_as_str(ptr) };
906 TrailingOffsetTypeOptional::from_str(value).unwrap_or_else(|_| {
907 panic!("invalid `TrailingOffsetTypeOptional` enum string value, was '{value}'")
908 })
909 })
910}
911
912#[unsafe(no_mangle)]
913pub extern "C" fn trigger_type_to_cstr(value: TriggerTypeOptional) -> *const c_char {
914 str_to_cstr(value.as_ref())
915}
916
917#[unsafe(no_mangle)]
927pub unsafe extern "C" fn trigger_type_from_cstr(ptr: *const c_char) -> TriggerTypeOptional {
928 abort_on_panic(|| {
929 let value = unsafe { cstr_as_str(ptr) };
930 TriggerTypeOptional::from_str(value).unwrap_or_else(|_| {
931 panic!("invalid `TriggerTypeOptional` enum string value, was '{value}'")
932 })
933 })
934}
935
936#[cfg(test)]
937mod tests {
938 use rstest::rstest;
939
940 use super::*;
941 use crate::enums::OrderSide;
942
943 #[rstest]
944 fn test_name() {
945 assert_eq!(OrderSideOptional::NoOrderSide.as_ref(), "NO_ORDER_SIDE");
946 assert_eq!(OrderSide::Buy.as_ref(), "BUY");
947 assert_eq!(OrderSide::Sell.as_ref(), "SELL");
948 }
949
950 #[rstest]
951 fn test_value() {
952 assert_eq!(OrderSideOptional::NoOrderSide as u8, 0);
953 assert_eq!(OrderSide::Buy as u8, 1);
954 assert_eq!(OrderSide::Sell as u8, 2);
955 }
956
957 #[rstest]
958 #[case(None, ContingencyTypeOptional::NoContingency, 0)]
959 #[case(Some(ContingencyType::Oco), ContingencyTypeOptional::Oco, 1)]
960 #[case(Some(ContingencyType::Oto), ContingencyTypeOptional::Oto, 2)]
961 #[case(Some(ContingencyType::Ouo), ContingencyTypeOptional::Ouo, 3)]
962 fn test_contingency_type_optional_preserves_abi_values(
963 #[case] value: Option<ContingencyType>,
964 #[case] ffi_value: ContingencyTypeOptional,
965 #[case] discriminant: u8,
966 ) {
967 assert_eq!(ContingencyTypeOptional::from(value), ffi_value);
968 assert_eq!(ffi_value.as_option(), value);
969 assert_eq!(ffi_value as u8, discriminant);
970 }
971
972 #[rstest]
973 #[case(None, TrailingOffsetTypeOptional::NoTrailingOffset, 0)]
974 #[case(Some(TrailingOffsetType::Price), TrailingOffsetTypeOptional::Price, 1)]
975 #[case(
976 Some(TrailingOffsetType::BasisPoints),
977 TrailingOffsetTypeOptional::BasisPoints,
978 2
979 )]
980 #[case(Some(TrailingOffsetType::Ticks), TrailingOffsetTypeOptional::Ticks, 3)]
981 #[case(
982 Some(TrailingOffsetType::PriceTier),
983 TrailingOffsetTypeOptional::PriceTier,
984 4
985 )]
986 fn test_trailing_offset_type_optional_preserves_abi_values(
987 #[case] value: Option<TrailingOffsetType>,
988 #[case] ffi_value: TrailingOffsetTypeOptional,
989 #[case] discriminant: u8,
990 ) {
991 assert_eq!(TrailingOffsetTypeOptional::from(value), ffi_value);
992 assert_eq!(ffi_value.as_option(), value);
993 assert_eq!(ffi_value as u8, discriminant);
994 }
995
996 #[rstest]
997 #[case(None, TriggerTypeOptional::NoTrigger, 0)]
998 #[case(Some(TriggerType::Default), TriggerTypeOptional::Default, 1)]
999 #[case(Some(TriggerType::LastPrice), TriggerTypeOptional::LastPrice, 2)]
1000 #[case(Some(TriggerType::MarkPrice), TriggerTypeOptional::MarkPrice, 3)]
1001 #[case(Some(TriggerType::IndexPrice), TriggerTypeOptional::IndexPrice, 4)]
1002 #[case(Some(TriggerType::BidAsk), TriggerTypeOptional::BidAsk, 5)]
1003 #[case(Some(TriggerType::DoubleLast), TriggerTypeOptional::DoubleLast, 6)]
1004 #[case(Some(TriggerType::DoubleBidAsk), TriggerTypeOptional::DoubleBidAsk, 7)]
1005 #[case(Some(TriggerType::LastOrBidAsk), TriggerTypeOptional::LastOrBidAsk, 8)]
1006 #[case(Some(TriggerType::MidPoint), TriggerTypeOptional::MidPoint, 9)]
1007 fn test_trigger_type_optional_preserves_abi_values(
1008 #[case] value: Option<TriggerType>,
1009 #[case] ffi_value: TriggerTypeOptional,
1010 #[case] discriminant: u8,
1011 ) {
1012 assert_eq!(TriggerTypeOptional::from(value), ffi_value);
1013 assert_eq!(ffi_value.as_option(), value);
1014 assert_eq!(ffi_value as u8, discriminant);
1015 }
1016}