tower_http/csrf/
future.rs1use std::future::Future;
2use std::pin::Pin;
3use std::task::{Context, Poll};
4
5use pin_project_lite::pin_project;
6
7pin_project! {
8 pub struct ResponseFuture<F>
12 where
13 F: Future,
14 {
15 #[pin]
16 kind: Kind<F>,
17 }
18}
19
20pin_project! {
21 #[project = KindProj]
22 enum Kind<F>
23 where
24 F: Future,
25 {
26 Future {
27 #[pin]
28 future: F,
29 },
30 Rejected {
31 response: Option<F::Output>,
32 },
33 }
34}
35
36impl<F> ResponseFuture<F>
37where
38 F: Future,
39{
40 pub(super) fn future(future: F) -> Self {
41 Self {
42 kind: Kind::Future { future },
43 }
44 }
45
46 pub(super) fn rejected(response: F::Output) -> Self {
47 Self {
48 kind: Kind::Rejected {
49 response: Some(response),
50 },
51 }
52 }
53}
54
55impl<F> Future for ResponseFuture<F>
56where
57 F: Future,
58{
59 type Output = F::Output;
60
61 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
62 match self.project().kind.project() {
63 KindProj::Future { future } => future.poll(cx),
64 KindProj::Rejected { response } => Poll::Ready(
65 response
66 .take()
67 .expect("ResponseFuture polled after completion"),
68 ),
69 }
70 }
71}