nautilus_model/ffi/identifiers/
instrument_id.rs1use std::{
17 collections::hash_map::DefaultHasher,
18 ffi::c_char,
19 hash::{Hash, Hasher},
20 str::FromStr,
21};
22
23use nautilus_core::ffi::string::{cstr_as_str, str_to_cstr};
24
25use crate::identifiers::{InstrumentId, Symbol, Venue};
26
27#[unsafe(no_mangle)]
28pub extern "C" fn instrument_id_new(symbol: Symbol, venue: Venue) -> InstrumentId {
29 InstrumentId::new(symbol, venue)
30}
31
32#[unsafe(no_mangle)]
38pub unsafe extern "C" fn instrument_id_check_parsing(ptr: *const c_char) -> *const c_char {
39 let value = unsafe { cstr_as_str(ptr) };
40 match InstrumentId::from_str(value) {
41 Ok(_) => str_to_cstr(""),
42 Err(e) => str_to_cstr(&e.to_string()),
43 }
44}
45
46#[unsafe(no_mangle)]
52pub unsafe extern "C" fn instrument_id_from_cstr(ptr: *const c_char) -> InstrumentId {
53 let value = unsafe { cstr_as_str(ptr) };
54 InstrumentId::from(value)
55}
56
57#[unsafe(no_mangle)]
59pub extern "C" fn instrument_id_to_cstr(instrument_id: &InstrumentId) -> *const c_char {
60 str_to_cstr(&instrument_id.to_string())
61}
62
63#[unsafe(no_mangle)]
64pub extern "C" fn instrument_id_hash(instrument_id: &InstrumentId) -> u64 {
65 let mut h = DefaultHasher::new();
66 instrument_id.hash(&mut h);
67 h.finish()
68}
69
70#[unsafe(no_mangle)]
71pub extern "C" fn instrument_id_is_synthetic(instrument_id: &InstrumentId) -> u8 {
72 u8::from(instrument_id.is_synthetic())
73}
74
75#[cfg(test)]
76pub mod stubs {
77 use std::str::FromStr;
78
79 use rstest::fixture;
80
81 use crate::identifiers::{InstrumentId, Symbol, Venue, stubs::*};
82
83 #[fixture]
84 pub fn btc_usdt_perp_binance() -> InstrumentId {
85 InstrumentId::from_str("BTCUSDT-PERP.BINANCE").unwrap()
86 }
87
88 #[fixture]
89 pub fn audusd_sim(symbol_aud_usd: Symbol, venue_sim: Venue) -> InstrumentId {
90 InstrumentId {
91 symbol: symbol_aud_usd,
92 venue: venue_sim,
93 }
94 }
95}
96
97#[cfg(test)]
101mod tests {
102 use std::ffi::CStr;
103
104 use rstest::rstest;
105
106 use super::{InstrumentId, *};
107 use crate::identifiers::{Symbol, Venue};
108
109 #[rstest]
110 fn test_to_cstr() {
111 unsafe {
112 let id = InstrumentId::from("ETH/USDT.BINANCE");
113 let result = instrument_id_to_cstr(&id);
114 assert_eq!(CStr::from_ptr(result).to_str().unwrap(), "ETH/USDT.BINANCE");
115 }
116 }
117
118 #[rstest]
119 fn test_to_cstr_and_back() {
120 unsafe {
121 let id = InstrumentId::from("ETH/USDT.BINANCE");
122 let result = instrument_id_to_cstr(&id);
123 let id2 = instrument_id_from_cstr(result);
124 assert_eq!(id, id2);
125 }
126 }
127
128 #[rstest]
129 fn test_from_symbol_and_back() {
130 unsafe {
131 let id = InstrumentId::new(Symbol::from("ETH/USDT"), Venue::from("BINANCE"));
132 let result = instrument_id_to_cstr(&id);
133 let id2 = instrument_id_from_cstr(result);
134 assert_eq!(id, id2);
135 }
136 }
137}