summaryrefslogtreecommitdiffstats
path: root/third_party/rust/hyper/src/service/oneshot.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/rust/hyper/src/service/oneshot.rs
parentInitial commit. (diff)
downloadfirefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz
firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/hyper/src/service/oneshot.rs')
-rw-r--r--third_party/rust/hyper/src/service/oneshot.rs73
1 files changed, 73 insertions, 0 deletions
diff --git a/third_party/rust/hyper/src/service/oneshot.rs b/third_party/rust/hyper/src/service/oneshot.rs
new file mode 100644
index 0000000000..2697af8f4c
--- /dev/null
+++ b/third_party/rust/hyper/src/service/oneshot.rs
@@ -0,0 +1,73 @@
+// TODO: Eventually to be replaced with tower_util::Oneshot.
+
+use pin_project_lite::pin_project;
+use tower_service::Service;
+
+use crate::common::{task, Future, Pin, Poll};
+
+pub(crate) fn oneshot<S, Req>(svc: S, req: Req) -> Oneshot<S, Req>
+where
+ S: Service<Req>,
+{
+ Oneshot {
+ state: State::NotReady { svc, req },
+ }
+}
+
+pin_project! {
+ // A `Future` consuming a `Service` and request, waiting until the `Service`
+ // is ready, and then calling `Service::call` with the request, and
+ // waiting for that `Future`.
+ #[allow(missing_debug_implementations)]
+ pub struct Oneshot<S: Service<Req>, Req> {
+ #[pin]
+ state: State<S, Req>,
+ }
+}
+
+pin_project! {
+ #[project = StateProj]
+ #[project_replace = StateProjOwn]
+ enum State<S: Service<Req>, Req> {
+ NotReady {
+ svc: S,
+ req: Req,
+ },
+ Called {
+ #[pin]
+ fut: S::Future,
+ },
+ Tmp,
+ }
+}
+
+impl<S, Req> Future for Oneshot<S, Req>
+where
+ S: Service<Req>,
+{
+ type Output = Result<S::Response, S::Error>;
+
+ fn poll(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Self::Output> {
+ let mut me = self.project();
+
+ loop {
+ match me.state.as_mut().project() {
+ StateProj::NotReady { ref mut svc, .. } => {
+ ready!(svc.poll_ready(cx))?;
+ // fallthrough out of the match's borrow
+ }
+ StateProj::Called { fut } => {
+ return fut.poll(cx);
+ }
+ StateProj::Tmp => unreachable!(),
+ }
+
+ match me.state.as_mut().project_replace(State::Tmp) {
+ StateProjOwn::NotReady { mut svc, req } => {
+ me.state.set(State::Called { fut: svc.call(req) });
+ }
+ _ => unreachable!(),
+ }
+ }
+ }
+}