nautilus_model/ffi/data/
deltas.rs1use nautilus_core::{
17 UnixNanos,
18 ffi::{abort_on_panic, cvec::CVec},
19};
20
21use crate::{
22 data::OrderBookDeltas, enums::BookAction, ffi::data::delta::OrderBookDeltaFfi,
23 identifiers::InstrumentId,
24};
25
26#[unsafe(no_mangle)]
38pub unsafe extern "C" fn orderbook_deltas_new(
39 instrument_id: InstrumentId,
40 deltas: &CVec,
41) -> *mut OrderBookDeltas {
42 let cloned_deltas = unsafe { deltas.as_slice::<OrderBookDeltaFfi>() }
43 .iter()
44 .copied()
45 .map(Into::into)
46 .collect();
47 Box::into_raw(Box::new(OrderBookDeltas::new(instrument_id, cloned_deltas)))
48}
49
50#[unsafe(no_mangle)]
61pub unsafe extern "C" fn orderbook_deltas_drop(deltas: *mut OrderBookDeltas) {
62 abort_on_panic(|| {
63 assert!(!deltas.is_null(), "`deltas` was NULL");
64 drop(unsafe { Box::from_raw(deltas) }); });
67}
68
69#[unsafe(no_mangle)]
72pub extern "C" fn orderbook_deltas_clone(deltas: &OrderBookDeltas) -> *mut OrderBookDeltas {
73 Box::into_raw(Box::new(deltas.clone()))
74}
75
76#[unsafe(no_mangle)]
77pub extern "C" fn orderbook_deltas_instrument_id(deltas: &OrderBookDeltas) -> InstrumentId {
78 deltas.instrument_id
79}
80
81#[unsafe(no_mangle)]
82pub extern "C" fn orderbook_deltas_vec_deltas(deltas: &OrderBookDeltas) -> CVec {
83 deltas
84 .deltas
85 .iter()
86 .copied()
87 .map(OrderBookDeltaFfi::from)
88 .collect::<Vec<_>>()
89 .into()
90}
91
92#[unsafe(no_mangle)]
96pub extern "C" fn orderbook_deltas_is_snapshot(deltas: &OrderBookDeltas) -> u8 {
97 deltas
98 .deltas
99 .first()
100 .map_or(0, |first| u8::from(first.action == BookAction::Clear))
101}
102
103#[unsafe(no_mangle)]
104pub extern "C" fn orderbook_deltas_flags(deltas: &OrderBookDeltas) -> u8 {
105 deltas.flags
106}
107
108#[unsafe(no_mangle)]
109pub extern "C" fn orderbook_deltas_sequence(deltas: &OrderBookDeltas) -> u64 {
110 deltas.sequence
111}
112
113#[unsafe(no_mangle)]
114pub extern "C" fn orderbook_deltas_ts_event(deltas: &OrderBookDeltas) -> UnixNanos {
115 deltas.ts_event
116}
117
118#[unsafe(no_mangle)]
119pub extern "C" fn orderbook_deltas_ts_init(deltas: &OrderBookDeltas) -> UnixNanos {
120 deltas.ts_init
121}
122
123#[unsafe(no_mangle)]
129pub unsafe extern "C" fn orderbook_deltas_vec_drop(v: CVec) {
130 let deltas = unsafe { v.into_vec::<OrderBookDeltaFfi>() };
131 drop(deltas); }
133
134#[cfg(test)]
135mod tests {
136 use rstest::rstest;
137
138 use super::*;
139 use crate::data::stubs::stub_delta;
140
141 #[rstest]
142 fn test_empty_delta_drop_returns_without_panic() {
143 unsafe { orderbook_deltas_vec_drop(CVec::empty()) };
144 }
145
146 #[rstest]
147 fn test_orderbook_deltas_new_clones_borrowed_buffer() {
148 let delta = stub_delta();
149 let mut caller_owned = vec![OrderBookDeltaFfi::from(delta)];
150 let cvec = CVec {
151 ptr: caller_owned.as_mut_ptr().cast(),
152 len: caller_owned.len(),
153 cap: caller_owned.capacity(),
154 };
155
156 let deltas_ptr = unsafe { orderbook_deltas_new(delta.instrument_id, &cvec) };
157
158 let deltas = unsafe { &*deltas_ptr };
160 assert_eq!(deltas.deltas, vec![delta]);
161 caller_owned[0].sequence += 1;
162 assert_ne!(deltas.deltas[0].sequence, caller_owned[0].sequence);
163
164 unsafe { orderbook_deltas_drop(deltas_ptr) };
165 }
166}