ts-webapi 0.4.11

Library for my web API projects
Documentation
//! A future defined at the time the middleware is called.

use core::{
    pin::Pin,
    task::{Context, Poll, ready},
};

use http::{Response, StatusCode};
use http_body::Body;
use pin_project_lite::pin_project;

pin_project! {
    /// A future defined at the time the middleware is called.
    pub struct DefinedFuture<F> {
        #[pin]
        inner: DefinedFutureKind<F>,
    }
}

pin_project! {
    #[project = DefinedFutureKindProj]
    enum DefinedFutureKind<F> {
        Proceeding {
            #[pin]
            future: F,
        },
        Status {
            status: StatusCode
        },
    }
}

impl<F> DefinedFuture<F> {
    /// This future should just return the given status.
    pub fn return_status(status: StatusCode) -> Self {
        Self {
            inner: DefinedFutureKind::Status { status },
        }
    }

    /// This future should proceed with the inner future.
    pub fn proceed(future: F) -> Self {
        Self {
            inner: DefinedFutureKind::Proceeding { future },
        }
    }
}

impl<B, F, E> Future for DefinedFuture<F>
where
    B: Body + Default,
    F: Future<Output = Result<Response<B>, E>>,
{
    type Output = Result<Response<B>, E>;

    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        let response = match self.project().inner.project() {
            DefinedFutureKindProj::Proceeding { future } => ready!(future.poll(cx))?,
            DefinedFutureKindProj::Status { status } => Response::builder()
                .status(*status)
                .body(B::default())
                .expect("error response should be valid response"),
        };
        Poll::Ready(Ok(response))
    }
}