ts_webapi/middleware/futures/
defined.rs1use core::{
4 pin::Pin,
5 task::{Context, Poll, ready},
6};
7
8use http::{Response, StatusCode};
9use http_body::Body;
10use pin_project_lite::pin_project;
11
12pin_project! {
13 pub struct DefinedFuture<F> {
15 #[pin]
16 inner: DefinedFutureKind<F>,
17 }
18}
19
20pin_project! {
21 #[project = DefinedFutureKindProj]
22 enum DefinedFutureKind<F> {
23 Proceeding {
24 #[pin]
25 future: F,
26 },
27 Status {
28 status: StatusCode
29 },
30 }
31}
32
33impl<F> DefinedFuture<F> {
34 pub fn return_status(status: StatusCode) -> Self {
36 Self {
37 inner: DefinedFutureKind::Status { status },
38 }
39 }
40
41 pub fn proceed(future: F) -> Self {
43 Self {
44 inner: DefinedFutureKind::Proceeding { future },
45 }
46 }
47}
48
49impl<B, F, E> Future for DefinedFuture<F>
50where
51 B: Body + Default,
52 F: Future<Output = Result<Response<B>, E>>,
53{
54 type Output = Result<Response<B>, E>;
55
56 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
57 let response = match self.project().inner.project() {
58 DefinedFutureKindProj::Proceeding { future } => ready!(future.poll(cx))?,
59 DefinedFutureKindProj::Status { status } => Response::builder()
60 .status(*status)
61 .body(B::default())
62 .expect("error response should be valid response"),
63 };
64 Poll::Ready(Ok(response))
65 }
66}