Skip to content

Commit b6bffe2

Browse files
davidpdrsnseanmonstar
authored andcommitted
feat: add TowerToHyperService
1 parent 72c1c67 commit b6bffe2

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,10 @@ mod common;
1212
pub mod rt;
1313
#[cfg(feature = "server")]
1414
pub mod server;
15+
#[cfg(all(
16+
any(feature = "http1", feature = "http2"),
17+
any(feature = "server", feature = "client")
18+
))]
19+
pub mod service;
1520

1621
mod error;

src/service.rs

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

0 commit comments

Comments
 (0)