use smallvec::SmallVec;
use crate::{
backend::{LocalOrderId, OrderIdError},
order_manager::{OrderManager, OrderRef, OrdersCapacitySpec},
instrument::InstrumentSpec,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum OrderTracker {
Remote(RemoteOrderTracker),
Client(ClientOrderTracker),
}
impl OrderTracker {
pub fn is_settled_neutral<
IS: InstrumentSpec,
CS: OrdersCapacitySpec,
>(
&self,
order_manager: &OrderManager<IS, CS>,
) -> Result<bool, OrderIdError> {
match self {
Self::Remote(
tracker,
) => tracker.is_settled_neutral(order_manager),
Self::Client(
tracker,
) => tracker.is_settled_neutral(order_manager),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ClientOrderTracker(LocalOrderId);
impl ClientOrderTracker {
pub(crate) fn new(
local_order_id: LocalOrderId,
) -> Self {
Self(local_order_id)
}
pub fn as_local_order_id(
&self,
) -> &LocalOrderId {
&self.0
}
pub fn into_local_order_id(
self,
) -> LocalOrderId {
self.0
}
pub fn is_settled_neutral<
IS: InstrumentSpec,
CS: OrdersCapacitySpec,
>(
&self,
order_manager: &OrderManager<IS, CS>,
) -> Result<bool, OrderIdError> {
let local_order_id = self.0;
match order_manager.find_order(&local_order_id) {
Ok(OrderRef::PendingClient {
pending_client_order: _,
pending_client_orders: _,
}) => Ok(false),
Err(_) => Ok(true),
_ => return local_order_id.err_invalid(),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct RemoteOrderTracker(LocalOrderId);
impl RemoteOrderTracker {
pub(crate) fn new(
local_order_id: LocalOrderId,
) -> Self {
Self(local_order_id)
}
pub fn as_local_order_id(
&self,
) -> &LocalOrderId {
&self.0
}
pub fn into_local_order_id(
self,
) -> LocalOrderId {
self.0
}
pub fn is_settled_neutral<
IS: InstrumentSpec,
CS: OrdersCapacitySpec,
>(
&self,
order_manager: &OrderManager<IS, CS>,
) -> Result<bool, OrderIdError> {
let local_order_id = self.0;
let is_settled_neutral = match order_manager.find_order(&local_order_id)? {
OrderRef::PendingClient {
pending_client_order: _,
pending_client_orders: _,
} => return local_order_id.err_invalid(),
OrderRef::PendingRemote {
pending_remote_order: _,
pending_remote_orders: _,
} => false,
OrderRef::WorkingRemote {
working_remote_order: _,
working_remote_orders: _,
} => false,
OrderRef::CompletedRemote {
completed_remote_order: _,
completed_remote_orders: _,
} => true,
};
Ok(is_settled_neutral)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ComplexOrderTracker<const INLINE_LEN: usize> {
pub parent: OrderTracker,
pub dependencies: SmallVec<[OrderTracker; INLINE_LEN]>,
}
impl<const INLINE_LEN: usize> ComplexOrderTracker<INLINE_LEN> {
pub fn is_settled_neutral<
IS: InstrumentSpec,
CS: OrdersCapacitySpec,
>(
&self,
order_manager: &OrderManager<IS, CS>,
) -> Result<bool, OrderIdError> {
if !self.parent.is_settled_neutral(order_manager)? {
return Ok(false);
}
for tracker in self.dependencies.iter() {
if !tracker.is_settled_neutral(order_manager)? {
return Ok(false);
}
}
Ok(true)
}
}