use std::{
convert::Infallible,
future::Future,
pin::Pin,
sync::Arc,
task::{Context, Poll},
};
pub struct ZonToHyperService<S> {
inner: Arc<S>,
}
impl<S> ZonToHyperService<S> {
pub fn new(zon_service: S) -> Self {
Self { inner: Arc::new(zon_service) }
}
}
impl<B, S> hyper::service::Service<http::Request<B>> for ZonToHyperService<S>
where
B: Send + 'static,
S: zon_core::HttpService<B> + Send + 'static,
{
type Response = http::Response<S::ResponseBody>;
type Error = Infallible;
type Future = ZonToHyperServiceFuture<B, S>;
fn call(&self, req: http::Request<B>) -> Self::Future {
let svc = self.inner.clone();
ZonToHyperServiceFuture::new(async move { Ok(svc.call_svc(req).await) })
}
}
type ZonToHyperServiceResult<B> = Result<http::Response<B>, Infallible>;
pub struct ZonToHyperServiceFuture<B, S>
where
B: Send,
S: zon_core::HttpService<B>,
{
inner: Pin<Box<dyn Future<Output = ZonToHyperServiceResult<S::ResponseBody>> + Send>>,
}
impl<B, S> ZonToHyperServiceFuture<B, S>
where
B: Send,
S: zon_core::HttpService<B>,
{
fn new(
inner: impl Future<Output = Result<http::Response<S::ResponseBody>, Infallible>>
+ Send
+ 'static,
) -> Self {
Self { inner: Box::pin(inner) }
}
}
impl<B, S> Future for ZonToHyperServiceFuture<B, S>
where
B: Send,
S: zon_core::HttpService<B>,
{
type Output = Result<http::Response<S::ResponseBody>, Infallible>;
#[inline]
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
self.inner.as_mut().poll(cx)
}
}