Rust client for DxFeed API
git clone --recurse-submodules [email protected]:spotgamma/dxfeed-rust-api.git
sudo apt install llvm-dev libclang-dev clang
git submodule update --recursive --remote
See the dxfeed-c-api for the underlying C API types.
dxfeed-rust-api/samples/quote_sub_example/src/main.rs
Lines 65 to 134 in a3d4946
const SUCCESS: i32 = dx::DXF_SUCCESS as i32; | |
fn main() -> anyhow::Result<()> { | |
let mut conn: dx::dxf_connection_t = std::ptr::null_mut(); | |
let mut sub: dx::dxf_subscription_t = std::ptr::null_mut(); | |
// This is a contrived example of using the `user_data` parameter. This could easily be a | |
// println! in the listener, but provides an illustrative example of how to pass unsafe objects | |
// over to a given listener | |
let mut writer = BufWriter::with_capacity(4096, io::stdout()); | |
let writer_ptr: *mut c_void = &mut writer as *mut _ as *mut c_void; | |
// scope to drop/free large vectors once consumed for setting up subscriptions. | |
let mut symbols: Vec<U32CString> = vec![]; | |
let sym_str = U32CString::from_str("AAPL")?; | |
symbols.push(sym_str); | |
let mut rsyms: Vec<*const i32> = symbols | |
.iter() | |
.map(|u32_sym| u32_sym.as_ptr() as *const i32) | |
.collect(); | |
let c_syms: *mut dx::dxf_const_string_t = | |
rsyms.as_mut_slice().as_ptr() as *mut dx::dxf_const_string_t; | |
let c_host = CString::new("demo.dxfeed.com:7300")?; | |
assert_eq!(SUCCESS, unsafe { | |
dx::dxf_create_connection( | |
c_host.as_ptr(), // const char* address, | |
Some(termination_listener), // dxf_conn_termination_notifier_t notifier, | |
Some(sub_listener), // dxf_conn_status_notifier_t conn_status_notifier, | |
None, // dxf_socket_thread_creation_notifier_t stcn, | |
None, // dxf_socket_thread_destruction_notifier_t stdn, | |
std::ptr::null_mut(), // void* user_data, | |
&mut conn, // OUT dxf_connection_t* connection); | |
) | |
}); | |
eprintln!("connected"); | |
// Listen to quote events. Other events: | |
// dx::DXF_ET_TIME_AND_SALE | dx::DXF_ET_GREEKS | dx::DXF_ET_TRADE | dx::DXF_ET_TRADE_ETH; | |
assert_eq!(SUCCESS, unsafe { | |
dx::dxf_create_subscription(conn, dx::DXF_ET_QUOTE, &mut sub) | |
}); | |
assert_eq!(SUCCESS, unsafe { | |
dx::dxf_attach_event_listener(sub, Some(evt_listener), writer_ptr) | |
}); | |
assert_eq!(SUCCESS, unsafe { | |
dx::dxf_add_symbols(sub, c_syms, symbols.len() as i32) | |
}); | |
eprintln!("Ctrl-c to stop"); | |
let ticks = tick(Duration::from_secs(60)); | |
let sig_events = sig_channel()?; | |
loop { | |
select! { | |
recv(ticks) -> _ => { | |
eprintln!("{:?}: Running...", SystemTime::now()); | |
} | |
recv(sig_events) -> sig => { | |
match sig { | |
result => { | |
eprintln!("Received {:?}. Quitting...", result); | |
break; | |
}, | |
} | |
} | |
} | |
} | |
assert_eq!(SUCCESS, unsafe { dx::dxf_close_subscription(sub) }); | |
let close_close_conn_result = unsafe { dx::dxf_close_connection(conn) }; | |
eprintln!("close_close_conn_result: {}", close_close_conn_result); |