saluki_io/net/util/
hyper.rs

1use std::{
2    future::Future,
3    pin::Pin,
4    task::{Context, Poll},
5};
6
7use pin_project_lite::pin_project;
8use tower::{util::Oneshot, ServiceExt};
9
10/// A Tower service converted into a Hyper service.
11#[derive(Debug, Copy, Clone)]
12pub struct TowerToHyperService<S> {
13    service: S,
14}
15
16impl<S> TowerToHyperService<S> {
17    /// Create a new `TowerToHyperService` from a Tower service.
18    pub fn new(tower_service: S) -> Self {
19        Self { service: tower_service }
20    }
21}
22
23impl<S, R> hyper::service::Service<R> for TowerToHyperService<S>
24where
25    S: tower::Service<R> + Clone,
26{
27    type Response = S::Response;
28    type Error = S::Error;
29    type Future = TowerToHyperServiceFuture<S, R>;
30
31    fn call(&self, req: R) -> Self::Future {
32        TowerToHyperServiceFuture {
33            future: self.service.clone().oneshot(req),
34        }
35    }
36}
37
38pin_project! {
39    /// Response future for [`TowerToHyperService`].
40    pub struct TowerToHyperServiceFuture<S, R>
41    where
42        S: tower::Service<R>,
43    {
44        #[pin]
45        future: Oneshot<S, R>,
46    }
47}
48
49impl<S, R> Future for TowerToHyperServiceFuture<S, R>
50where
51    S: tower::Service<R>,
52{
53    type Output = Result<S::Response, S::Error>;
54
55    #[inline]
56    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
57        self.project().future.poll(cx)
58    }
59}