tower/load_shed/
future.rs
1use std::fmt;
4use std::future::Future;
5use std::pin::Pin;
6use std::task::{Context, Poll};
7
8use futures_core::ready;
9use pin_project_lite::pin_project;
10
11use super::error::Overloaded;
12
13pin_project! {
14 pub struct ResponseFuture<F> {
18 #[pin]
19 state: ResponseState<F>,
20 }
21}
22
23pin_project! {
24 #[project = ResponseStateProj]
25 enum ResponseState<F> {
26 Called {
27 #[pin]
28 fut: F
29 },
30 Overloaded,
31 }
32}
33
34impl<F> ResponseFuture<F> {
35 pub(crate) fn called(fut: F) -> Self {
36 ResponseFuture {
37 state: ResponseState::Called { fut },
38 }
39 }
40
41 pub(crate) fn overloaded() -> Self {
42 ResponseFuture {
43 state: ResponseState::Overloaded,
44 }
45 }
46}
47
48impl<F, T, E> Future for ResponseFuture<F>
49where
50 F: Future<Output = Result<T, E>>,
51 E: Into<crate::BoxError>,
52{
53 type Output = Result<T, crate::BoxError>;
54
55 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
56 match self.project().state.project() {
57 ResponseStateProj::Called { fut } => {
58 Poll::Ready(ready!(fut.poll(cx)).map_err(Into::into))
59 }
60 ResponseStateProj::Overloaded => Poll::Ready(Err(Overloaded::new().into())),
61 }
62 }
63}
64
65impl<F> fmt::Debug for ResponseFuture<F>
66where
67 F: fmt::Debug,
69{
70 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
71 f.write_str("ResponseFuture")
72 }
73}