hyper/service/
oneshot.rs

1// TODO: Eventually to be replaced with tower_util::Oneshot.
2
3use pin_project_lite::pin_project;
4use tower_service::Service;
5
6use crate::common::{task, Future, Pin, Poll};
7
8pub(crate) fn oneshot<S, Req>(svc: S, req: Req) -> Oneshot<S, Req>
9where
10    S: Service<Req>,
11{
12    Oneshot {
13        state: State::NotReady { svc, req },
14    }
15}
16
17pin_project! {
18    // A `Future` consuming a `Service` and request, waiting until the `Service`
19    // is ready, and then calling `Service::call` with the request, and
20    // waiting for that `Future`.
21    #[allow(missing_debug_implementations)]
22    pub struct Oneshot<S: Service<Req>, Req> {
23        #[pin]
24        state: State<S, Req>,
25    }
26}
27
28pin_project! {
29    #[project = StateProj]
30    #[project_replace = StateProjOwn]
31    enum State<S: Service<Req>, Req> {
32        NotReady {
33            svc: S,
34            req: Req,
35        },
36        Called {
37            #[pin]
38            fut: S::Future,
39        },
40        Tmp,
41    }
42}
43
44impl<S, Req> Future for Oneshot<S, Req>
45where
46    S: Service<Req>,
47{
48    type Output = Result<S::Response, S::Error>;
49
50    fn poll(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Self::Output> {
51        let mut me = self.project();
52
53        loop {
54            match me.state.as_mut().project() {
55                StateProj::NotReady { ref mut svc, .. } => {
56                    ready!(svc.poll_ready(cx))?;
57                    // fallthrough out of the match's borrow
58                }
59                StateProj::Called { fut } => {
60                    return fut.poll(cx);
61                }
62                StateProj::Tmp => unreachable!(),
63            }
64
65            match me.state.as_mut().project_replace(State::Tmp) {
66                StateProjOwn::NotReady { mut svc, req } => {
67                    me.state.set(State::Called { fut: svc.call(req) });
68                }
69                _ => unreachable!(),
70            }
71        }
72    }
73}