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