Skip to main content

nautilus_plugin/surfaces/
book.rs

1// -------------------------------------------------------------------------------------------------
2//  Copyright (C) 2015-2026 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
16//! Boundary-owned handles for order book payloads.
17//!
18//! [`OrderBook`] and [`OrderBookDeltas`] own Rust collection state and
19//! cannot be `#[repr(C)]`, so the host wraps each value in a `#[repr(C)]`
20//! handle that owns the boxed value and passes a borrowed pointer to the
21//! plug-in. The plug-in's thunk dereferences the handle once and hands an
22//! `&OrderBook` or `&OrderBookDeltas` to the trait method. The deltas
23//! handle mirrors the ownership contract that
24//! [`OrderBookDeltas_API`](nautilus_model::data::OrderBookDeltas_API)
25//! uses for the Cython FFI surface.
26
27#![allow(unsafe_code)]
28
29use std::ops::Deref;
30
31use nautilus_model::{data::OrderBookDeltas, orderbook::OrderBook};
32
33/// Boundary-owned wrapper that lets [`OrderBook`] cross the cdylib FFI
34/// boundary by reference.
35///
36/// The host constructs an instance from a cloned book, hands a
37/// `*const OrderBookHandle` to the plug-in for the duration of the
38/// callback, and drops the handle when the call returns. The plug-in
39/// only borrows the handle and never owns it.
40#[repr(C)]
41#[derive(Debug, Clone)]
42pub struct OrderBookHandle(Box<OrderBook>);
43
44impl OrderBookHandle {
45    /// Wraps `book` in a boundary-owned handle.
46    #[must_use]
47    pub fn new(book: OrderBook) -> Self {
48        Self(Box::new(book))
49    }
50
51    /// Returns a reference to the wrapped book.
52    #[must_use]
53    pub fn book(&self) -> &OrderBook {
54        &self.0
55    }
56
57    /// Consumes the wrapper and returns the inner book.
58    #[must_use]
59    pub fn into_inner(self) -> OrderBook {
60        *self.0
61    }
62}
63
64impl Deref for OrderBookHandle {
65    type Target = OrderBook;
66
67    fn deref(&self) -> &Self::Target {
68        &self.0
69    }
70}
71
72/// Boundary-owned wrapper that lets [`OrderBookDeltas`] cross the cdylib
73/// FFI boundary by reference.
74///
75/// The host constructs an instance, hands a
76/// `*const OrderBookDeltasHandle` to the plug-in for the duration of the
77/// callback, and drops the handle when the call returns. The plug-in
78/// only borrows the handle and never owns it.
79#[repr(C)]
80#[derive(Debug, Clone)]
81pub struct OrderBookDeltasHandle(Box<OrderBookDeltas>);
82
83impl OrderBookDeltasHandle {
84    /// Wraps `deltas` in a boundary-owned handle.
85    #[must_use]
86    pub fn new(deltas: OrderBookDeltas) -> Self {
87        Self(Box::new(deltas))
88    }
89
90    /// Returns a reference to the wrapped deltas.
91    #[must_use]
92    pub fn deltas(&self) -> &OrderBookDeltas {
93        &self.0
94    }
95
96    /// Consumes the wrapper and returns the inner deltas.
97    #[must_use]
98    pub fn into_inner(self) -> OrderBookDeltas {
99        *self.0
100    }
101}
102
103impl Deref for OrderBookDeltasHandle {
104    type Target = OrderBookDeltas;
105
106    fn deref(&self) -> &Self::Target {
107        &self.0
108    }
109}