use http::{response, Request};
pub trait OnDropCallback: Send + 'static {
fn on_drop(self);
}
impl<F> OnDropCallback for F
where
F: FnOnce() + Send + 'static,
{
fn on_drop(self) {
self()
}
}
#[derive(Debug, Clone, Copy)]
pub struct NoopDropCallback;
impl OnDropCallback for NoopDropCallback {
fn on_drop(self) {}
}
pub trait OnFutureDrop<ReqB> {
type Callback: OnDropCallback;
fn make(&mut self, request: &Request<ReqB>) -> Self::Callback;
}
impl<F, C, ReqB> OnFutureDrop<ReqB> for F
where
F: FnMut(&Request<ReqB>) -> C,
C: OnDropCallback,
{
type Callback = C;
fn make(&mut self, request: &Request<ReqB>) -> Self::Callback {
(self)(request)
}
}
impl<ReqB> OnFutureDrop<ReqB> for () {
type Callback = NoopDropCallback;
fn make(&mut self, _request: &Request<ReqB>) -> Self::Callback {
NoopDropCallback
}
}
pub trait OnBodyDrop<ReqB> {
type Intermediate: Send + 'static;
type Callback: OnDropCallback;
fn make_at_call(&mut self, request: &Request<ReqB>) -> Self::Intermediate;
fn make_at_response(
&mut self,
intermediate: Self::Intermediate,
response_parts: &response::Parts,
) -> Self::Callback;
}
impl<ReqB> OnBodyDrop<ReqB> for () {
type Intermediate = ();
type Callback = NoopDropCallback;
fn make_at_call(&mut self, _request: &Request<ReqB>) -> Self::Intermediate {}
fn make_at_response(
&mut self,
_intermediate: Self::Intermediate,
_response_parts: &response::Parts,
) -> Self::Callback {
NoopDropCallback
}
}
#[derive(Clone, Copy)]
pub struct OnBodyDropFn<F>(F);
impl<F> OnBodyDropFn<F> {
pub fn new(f: F) -> Self {
Self(f)
}
}
impl<F> std::fmt::Debug for OnBodyDropFn<F> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("OnBodyDropFn").finish_non_exhaustive()
}
}
impl<F, G, C, ReqB> OnBodyDrop<ReqB> for OnBodyDropFn<F>
where
F: FnMut(&Request<ReqB>) -> G,
G: FnOnce(&response::Parts) -> C + Send + 'static,
C: OnDropCallback,
{
type Intermediate = G;
type Callback = C;
fn make_at_call(&mut self, request: &Request<ReqB>) -> Self::Intermediate {
(self.0)(request)
}
fn make_at_response(
&mut self,
intermediate: Self::Intermediate,
response_parts: &response::Parts,
) -> Self::Callback {
(intermediate)(response_parts)
}
}