zon_hyper 0.0.2

part of a new WIP, very incomplete async http service stack
Documentation
use std::{
    convert::Infallible,
    future::Future,
    pin::Pin,
    task::{Context, Poll},
};

/// Wraps a zon [`HttpService`][zon_core::HttpService] and implements
/// [`hyper::service::Service`].
///
/// The zon service needs to implement [`Clone`]. If you have a service that
/// doesn't, you can trivially make one that does from it by wrapping it in an
/// [`Arc`][std::sync::Arc] first.
pub struct ZonToHyperService<S> {
    inner: S,
}

impl<S> ZonToHyperService<S> {
    /// Create a new `ZonToHyperService` from a tower service.
    pub fn new(zon_service: S) -> Self {
        Self { inner: zon_service }
    }
}

impl<B, S> hyper::service::Service<http::Request<B>> for ZonToHyperService<S>
where
    B: Send + 'static,
    S: zon_core::HttpService<B> + Clone + 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(req).await) })
    }
}

type ZonToHyperServiceResult<B> = Result<http::Response<B>, Infallible>;

/// Response future for [`ZonToHyperService`].
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)
    }
}