nautilus_model/ffi/
enums.rs

1// -------------------------------------------------------------------------------------------------
2//  Copyright (C) 2015-2025 Nautech Systems Pty Ltd. All rights reserved.
3//  https://nautechsystems.io
4//
5//  Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6//  You may not use this file except in compliance with the License.
7//  You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8//
9//  Unless required by applicable law or agreed to in writing, software
10//  distributed under the License is distributed on an "AS IS" BASIS,
11//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//  See the License for the specific language governing permissions and
13//  limitations under the License.
14// -------------------------------------------------------------------------------------------------
15
16use std::{ffi::c_char, str::FromStr};
17
18use nautilus_core::ffi::string::{cstr_as_str, str_to_cstr};
19
20use crate::enums::{
21    AccountType, AggregationSource, AggressorSide, AssetClass, BarAggregation, BookAction,
22    BookType, ContingencyType, CurrencyType, InstrumentClass, InstrumentCloseType, LiquiditySide,
23    MarketStatus, MarketStatusAction, OmsType, OptionKind, OrderSide, OrderStatus, OrderType,
24    PositionSide, PriceType, RecordFlag, TimeInForce, TradingState, TrailingOffsetType,
25    TriggerType,
26};
27
28#[no_mangle]
29pub extern "C" fn account_type_to_cstr(value: AccountType) -> *const c_char {
30    str_to_cstr(value.as_ref())
31}
32
33/// Returns an enum from a Python string.
34///
35/// # Safety
36///
37/// - Assumes `ptr` is a valid C string pointer.
38#[no_mangle]
39pub unsafe extern "C" fn account_type_from_cstr(ptr: *const c_char) -> AccountType {
40    let value = cstr_as_str(ptr);
41    AccountType::from_str(value)
42        .unwrap_or_else(|_| panic!("invalid `AccountType` enum string value, was '{value}'"))
43}
44
45#[no_mangle]
46pub extern "C" fn aggregation_source_to_cstr(value: AggregationSource) -> *const c_char {
47    str_to_cstr(value.as_ref())
48}
49
50/// Returns an enum from a Python string.
51///
52/// # Safety
53///
54/// - Assumes `ptr` is a valid C string pointer.
55#[no_mangle]
56pub unsafe extern "C" fn aggregation_source_from_cstr(ptr: *const c_char) -> AggregationSource {
57    let value = cstr_as_str(ptr);
58    AggregationSource::from_str(value)
59        .unwrap_or_else(|_| panic!("invalid `AggregationSource` enum string value, was '{value}'"))
60}
61
62#[no_mangle]
63pub extern "C" fn aggressor_side_to_cstr(value: AggressorSide) -> *const c_char {
64    str_to_cstr(value.as_ref())
65}
66
67/// Returns an enum from a Python string.
68///
69/// # Safety
70///
71/// - Assumes `ptr` is a valid C string pointer.
72#[no_mangle]
73pub unsafe extern "C" fn aggressor_side_from_cstr(ptr: *const c_char) -> AggressorSide {
74    let value = cstr_as_str(ptr);
75    AggressorSide::from_str(value)
76        .unwrap_or_else(|_| panic!("invalid `AggressorSide` enum string value, was '{value}'"))
77}
78
79#[no_mangle]
80pub extern "C" fn asset_class_to_cstr(value: AssetClass) -> *const c_char {
81    str_to_cstr(value.as_ref())
82}
83
84/// Returns an enum from a Python string.
85///
86/// # Safety
87///
88/// - Assumes `ptr` is a valid C string pointer.
89#[no_mangle]
90pub unsafe extern "C" fn asset_class_from_cstr(ptr: *const c_char) -> AssetClass {
91    let value = cstr_as_str(ptr);
92    AssetClass::from_str(value)
93        .unwrap_or_else(|_| panic!("invalid `AssetClass` enum string value, was '{value}'"))
94}
95
96#[no_mangle]
97pub extern "C" fn instrument_class_to_cstr(value: InstrumentClass) -> *const c_char {
98    str_to_cstr(value.as_ref())
99}
100
101/// Returns an enum from a Python string.
102///
103/// # Safety
104///
105/// - Assumes `ptr` is a valid C string pointer.
106#[no_mangle]
107pub unsafe extern "C" fn instrument_class_from_cstr(ptr: *const c_char) -> InstrumentClass {
108    let value = cstr_as_str(ptr);
109    InstrumentClass::from_str(value)
110        .unwrap_or_else(|_| panic!("invalid `InstrumentClass` enum string value, was '{value}'"))
111}
112
113#[no_mangle]
114pub extern "C" fn bar_aggregation_to_cstr(value: BarAggregation) -> *const c_char {
115    str_to_cstr(value.as_ref())
116}
117
118/// Returns an enum from a Python string.
119///
120/// # Safety
121///
122/// - Assumes `ptr` is a valid C string pointer.
123#[no_mangle]
124pub unsafe extern "C" fn bar_aggregation_from_cstr(ptr: *const c_char) -> BarAggregation {
125    let value = cstr_as_str(ptr);
126    BarAggregation::from_str(value)
127        .unwrap_or_else(|_| panic!("invalid `BarAggregation` enum string value, was '{value}'"))
128}
129
130#[no_mangle]
131pub extern "C" fn book_action_to_cstr(value: BookAction) -> *const c_char {
132    str_to_cstr(value.as_ref())
133}
134
135/// Returns an enum from a Python string.
136///
137/// # Safety
138///
139/// - Assumes `ptr` is a valid C string pointer.
140#[no_mangle]
141pub unsafe extern "C" fn book_action_from_cstr(ptr: *const c_char) -> BookAction {
142    let value = cstr_as_str(ptr);
143    BookAction::from_str(value)
144        .unwrap_or_else(|_| panic!("invalid `BookAction` enum string value, was '{value}'"))
145}
146
147#[no_mangle]
148pub extern "C" fn book_type_to_cstr(value: BookType) -> *const c_char {
149    str_to_cstr(value.as_ref())
150}
151
152/// Returns an enum from a Python string.
153///
154/// # Safety
155///
156/// - Assumes `ptr` is a valid C string pointer.
157#[no_mangle]
158pub unsafe extern "C" fn book_type_from_cstr(ptr: *const c_char) -> BookType {
159    let value = cstr_as_str(ptr);
160    BookType::from_str(value)
161        .unwrap_or_else(|_| panic!("invalid `BookType` enum string value, was '{value}'"))
162}
163
164#[no_mangle]
165pub extern "C" fn contingency_type_to_cstr(value: ContingencyType) -> *const c_char {
166    str_to_cstr(value.as_ref())
167}
168
169/// Returns an enum from a Python string.
170///
171/// # Safety
172///
173/// - Assumes `ptr` is a valid C string pointer.
174#[no_mangle]
175pub unsafe extern "C" fn contingency_type_from_cstr(ptr: *const c_char) -> ContingencyType {
176    let value = cstr_as_str(ptr);
177    ContingencyType::from_str(value)
178        .unwrap_or_else(|_| panic!("invalid `ContingencyType` enum string value, was '{value}'"))
179}
180
181#[no_mangle]
182pub extern "C" fn currency_type_to_cstr(value: CurrencyType) -> *const c_char {
183    str_to_cstr(value.as_ref())
184}
185
186/// Returns an enum from a Python string.
187///
188/// # Safety
189///
190/// - Assumes `ptr` is a valid C string pointer.
191#[no_mangle]
192pub unsafe extern "C" fn currency_type_from_cstr(ptr: *const c_char) -> CurrencyType {
193    let value = cstr_as_str(ptr);
194    CurrencyType::from_str(value)
195        .unwrap_or_else(|_| panic!("invalid `CurrencyType` enum string value, was '{value}'"))
196}
197
198/// Returns an enum from a Python string.
199///
200/// # Safety
201///
202/// - Assumes `ptr` is a valid C string pointer.
203#[no_mangle]
204pub unsafe extern "C" fn instrument_close_type_from_cstr(
205    ptr: *const c_char,
206) -> InstrumentCloseType {
207    let value = cstr_as_str(ptr);
208    InstrumentCloseType::from_str(value).unwrap_or_else(|_| {
209        panic!("invalid `InstrumentCloseType` enum string value, was '{value}'")
210    })
211}
212
213#[no_mangle]
214pub extern "C" fn instrument_close_type_to_cstr(value: InstrumentCloseType) -> *const c_char {
215    str_to_cstr(value.as_ref())
216}
217
218#[no_mangle]
219pub extern "C" fn liquidity_side_to_cstr(value: LiquiditySide) -> *const c_char {
220    str_to_cstr(value.as_ref())
221}
222
223/// Returns an enum from a Python string.
224///
225/// # Safety
226///
227/// - Assumes `ptr` is a valid C string pointer.
228#[no_mangle]
229pub unsafe extern "C" fn liquidity_side_from_cstr(ptr: *const c_char) -> LiquiditySide {
230    let value = cstr_as_str(ptr);
231    LiquiditySide::from_str(value)
232        .unwrap_or_else(|_| panic!("invalid `LiquiditySide` enum string value, was '{value}'"))
233}
234
235#[no_mangle]
236pub extern "C" fn market_status_to_cstr(value: MarketStatus) -> *const c_char {
237    str_to_cstr(value.as_ref())
238}
239
240/// Returns an enum from a Python string.
241///
242/// # Safety
243///
244/// - Assumes `ptr` is a valid C string pointer.
245#[no_mangle]
246pub unsafe extern "C" fn market_status_from_cstr(ptr: *const c_char) -> MarketStatus {
247    let value = cstr_as_str(ptr);
248    MarketStatus::from_str(value)
249        .unwrap_or_else(|_| panic!("invalid `MarketStatus` enum string value, was '{value}'"))
250}
251
252#[no_mangle]
253pub extern "C" fn market_status_action_to_cstr(value: MarketStatusAction) -> *const c_char {
254    str_to_cstr(value.as_ref())
255}
256
257/// Returns an enum from a Python string.
258///
259/// # Safety
260///
261/// - Assumes `ptr` is a valid C string pointer.
262#[no_mangle]
263pub unsafe extern "C" fn market_status_action_from_cstr(ptr: *const c_char) -> MarketStatusAction {
264    let value = cstr_as_str(ptr);
265    MarketStatusAction::from_str(value)
266        .unwrap_or_else(|_| panic!("invalid `MarketStatusAction` enum string value, was '{value}'"))
267}
268
269#[no_mangle]
270pub extern "C" fn oms_type_to_cstr(value: OmsType) -> *const c_char {
271    str_to_cstr(value.as_ref())
272}
273
274/// Returns an enum from a Python string.
275///
276/// # Safety
277///
278/// - Assumes `ptr` is a valid C string pointer.
279#[no_mangle]
280pub unsafe extern "C" fn oms_type_from_cstr(ptr: *const c_char) -> OmsType {
281    let value = cstr_as_str(ptr);
282    OmsType::from_str(value)
283        .unwrap_or_else(|_| panic!("invalid `OmsType` enum string value, was '{value}'"))
284}
285
286#[no_mangle]
287pub extern "C" fn option_kind_to_cstr(value: OptionKind) -> *const c_char {
288    str_to_cstr(value.as_ref())
289}
290
291/// Returns an enum from a Python string.
292///
293/// # Safety
294///
295/// - Assumes `ptr` is a valid C string pointer.
296#[no_mangle]
297pub unsafe extern "C" fn option_kind_from_cstr(ptr: *const c_char) -> OptionKind {
298    let value = cstr_as_str(ptr);
299    OptionKind::from_str(value)
300        .unwrap_or_else(|_| panic!("invalid `OptionKind` enum string value, was '{value}'"))
301}
302
303#[no_mangle]
304pub extern "C" fn order_side_to_cstr(value: OrderSide) -> *const c_char {
305    str_to_cstr(value.as_ref())
306}
307
308/// Returns an enum from a Python string.
309///
310/// # Safety
311///
312/// - Assumes `ptr` is a valid C string pointer.
313#[no_mangle]
314pub unsafe extern "C" fn order_side_from_cstr(ptr: *const c_char) -> OrderSide {
315    let value = cstr_as_str(ptr);
316    OrderSide::from_str(value)
317        .unwrap_or_else(|_| panic!("invalid `OrderSide` enum string value, was '{value}'"))
318}
319
320#[no_mangle]
321pub extern "C" fn order_status_to_cstr(value: OrderStatus) -> *const c_char {
322    str_to_cstr(value.as_ref())
323}
324
325/// Returns an enum from a Python string.
326///
327/// # Safety
328///
329/// - Assumes `ptr` is a valid C string pointer.
330#[no_mangle]
331pub unsafe extern "C" fn order_status_from_cstr(ptr: *const c_char) -> OrderStatus {
332    let value = cstr_as_str(ptr);
333    OrderStatus::from_str(value)
334        .unwrap_or_else(|_| panic!("invalid `OrderStatus` enum string value, was '{value}'"))
335}
336
337#[no_mangle]
338pub extern "C" fn order_type_to_cstr(value: OrderType) -> *const c_char {
339    str_to_cstr(value.as_ref())
340}
341
342/// Returns an enum from a Python string.
343///
344/// # Safety
345///
346/// - Assumes `ptr` is a valid C string pointer.
347#[no_mangle]
348pub unsafe extern "C" fn order_type_from_cstr(ptr: *const c_char) -> OrderType {
349    let value = cstr_as_str(ptr);
350    OrderType::from_str(value)
351        .unwrap_or_else(|_| panic!("invalid `OrderType` enum string value, was '{value}'"))
352}
353
354#[no_mangle]
355pub extern "C" fn position_side_to_cstr(value: PositionSide) -> *const c_char {
356    str_to_cstr(value.as_ref())
357}
358
359/// Returns an enum from a Python string.
360///
361/// # Safety
362///
363/// - Assumes `ptr` is a valid C string pointer.
364#[no_mangle]
365pub unsafe extern "C" fn position_side_from_cstr(ptr: *const c_char) -> PositionSide {
366    let value = cstr_as_str(ptr);
367    PositionSide::from_str(value)
368        .unwrap_or_else(|_| panic!("invalid `PositionSide` enum string value, was '{value}'"))
369}
370
371#[no_mangle]
372pub extern "C" fn price_type_to_cstr(value: PriceType) -> *const c_char {
373    str_to_cstr(value.as_ref())
374}
375
376/// Returns an enum from a Python string.
377///
378/// # Safety
379///
380/// - Assumes `ptr` is a valid C string pointer.
381#[no_mangle]
382pub unsafe extern "C" fn price_type_from_cstr(ptr: *const c_char) -> PriceType {
383    let value = cstr_as_str(ptr);
384    PriceType::from_str(value)
385        .unwrap_or_else(|_| panic!("invalid `PriceType` enum string value, was '{value}'"))
386}
387
388#[no_mangle]
389pub extern "C" fn record_flag_to_cstr(value: RecordFlag) -> *const c_char {
390    str_to_cstr(value.as_ref())
391}
392
393/// Returns an enum from a Python string.
394///
395/// # Safety
396///
397/// - Assumes `ptr` is a valid C string pointer.
398#[no_mangle]
399pub unsafe extern "C" fn record_flag_from_cstr(ptr: *const c_char) -> RecordFlag {
400    let value = cstr_as_str(ptr);
401    RecordFlag::from_str(value)
402        .unwrap_or_else(|_| panic!("invalid `RecordFlag` enum string value, was '{value}'"))
403}
404
405#[no_mangle]
406pub extern "C" fn time_in_force_to_cstr(value: TimeInForce) -> *const c_char {
407    str_to_cstr(value.as_ref())
408}
409
410/// Returns an enum from a Python string.
411///
412/// # Safety
413///
414/// - Assumes `ptr` is a valid C string pointer.
415#[no_mangle]
416pub unsafe extern "C" fn time_in_force_from_cstr(ptr: *const c_char) -> TimeInForce {
417    let value = cstr_as_str(ptr);
418    TimeInForce::from_str(value)
419        .unwrap_or_else(|_| panic!("invalid `TimeInForce` enum string value, was '{value}'"))
420}
421
422#[no_mangle]
423pub extern "C" fn trading_state_to_cstr(value: TradingState) -> *const c_char {
424    str_to_cstr(value.as_ref())
425}
426
427/// Returns an enum from a Python string.
428///
429/// # Safety
430///
431/// - Assumes `ptr` is a valid C string pointer.
432#[no_mangle]
433pub unsafe extern "C" fn trading_state_from_cstr(ptr: *const c_char) -> TradingState {
434    let value = cstr_as_str(ptr);
435    TradingState::from_str(value)
436        .unwrap_or_else(|_| panic!("invalid `TradingState` enum string value, was '{value}'"))
437}
438
439#[no_mangle]
440pub extern "C" fn trailing_offset_type_to_cstr(value: TrailingOffsetType) -> *const c_char {
441    str_to_cstr(value.as_ref())
442}
443
444/// Returns an enum from a Python string.
445///
446/// # Safety
447///
448/// - Assumes `ptr` is a valid C string pointer.
449#[no_mangle]
450pub unsafe extern "C" fn trailing_offset_type_from_cstr(ptr: *const c_char) -> TrailingOffsetType {
451    let value = cstr_as_str(ptr);
452    TrailingOffsetType::from_str(value)
453        .unwrap_or_else(|_| panic!("invalid `TrailingOffsetType` enum string value, was '{value}'"))
454}
455
456#[no_mangle]
457pub extern "C" fn trigger_type_to_cstr(value: TriggerType) -> *const c_char {
458    str_to_cstr(value.as_ref())
459}
460
461/// Returns an enum from a Python string.
462///
463/// # Safety
464///
465/// - Assumes `ptr` is a valid C string pointer.
466#[no_mangle]
467pub unsafe extern "C" fn trigger_type_from_cstr(ptr: *const c_char) -> TriggerType {
468    let value = cstr_as_str(ptr);
469    TriggerType::from_str(value)
470        .unwrap_or_else(|_| panic!("invalid `TriggerType` enum string value, was '{value}'"))
471}
472
473#[cfg(test)]
474mod tests {
475    use rstest::rstest;
476
477    use super::*;
478
479    #[rstest]
480    fn test_name() {
481        assert_eq!(OrderSide::NoOrderSide.name(), "NO_ORDER_SIDE");
482        assert_eq!(OrderSide::Buy.name(), "BUY");
483        assert_eq!(OrderSide::Sell.name(), "SELL");
484    }
485
486    #[rstest]
487    fn test_value() {
488        assert_eq!(OrderSide::NoOrderSide.value(), 0);
489        assert_eq!(OrderSide::Buy.value(), 1);
490        assert_eq!(OrderSide::Sell.value(), 2);
491    }
492}