use super::reject::Rejects;
use super::reservation::PreTradeReservation;
pub struct PreTradeRequest<O> {
inner: Box<dyn RequestHandle<O>>,
}
pub(crate) trait RequestHandle<O> {
fn execute(self: Box<Self>) -> Result<PreTradeReservation, Rejects>;
}
impl<O> std::fmt::Debug for PreTradeRequest<O> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("PreTradeRequest").finish_non_exhaustive()
}
}
impl<O> PreTradeRequest<O> {
pub fn execute(self) -> Result<PreTradeReservation, Rejects> {
self.inner.execute()
}
pub(crate) fn from_handle(inner: Box<dyn RequestHandle<O>>) -> Self {
Self { inner }
}
}
#[cfg(test)]
mod tests {
use super::PreTradeRequest;
use crate::pretrade::handle::RequestHandleImpl;
use crate::pretrade::PreTradeReservation;
#[test]
fn execute_consumes_request_and_delegates_to_handle() {
let request =
PreTradeRequest::<()>::from_handle(Box::new(RequestHandleImpl::new(Box::new(|| {
Ok(PreTradeReservation::from_handle(Box::new(
NoopReservationHandle,
)))
}))));
let mut reservation = request.execute().expect("request execution must succeed");
reservation.commit();
}
#[test]
fn execute_can_finalize_returned_reservation_with_rollback() {
let request =
PreTradeRequest::<()>::from_handle(Box::new(RequestHandleImpl::new(Box::new(|| {
Ok(PreTradeReservation::from_handle(Box::new(
NoopReservationHandle,
)))
}))));
let mut reservation = request.execute().expect("request execution must succeed");
reservation.rollback();
}
#[test]
fn debug_format_is_opaque() {
let request =
PreTradeRequest::<()>::from_handle(Box::new(RequestHandleImpl::new(Box::new(|| {
Ok(PreTradeReservation::from_handle(Box::new(
NoopReservationHandle,
)))
}))));
assert!(format!("{request:?}").contains("PreTradeRequest"));
drop(request.execute());
}
struct NoopReservationHandle;
impl crate::pretrade::reservation::ReservationHandle for NoopReservationHandle {
fn commit(self: Box<Self>) {}
fn rollback(self: Box<Self>) {}
fn lock(&self) -> crate::pretrade::PreTradeLock {
crate::pretrade::PreTradeLock::default()
}
}
}