keclc-framed 0.1.0

kayrx framed app server
Documentation
use std::task::{Context, Poll};

use kayrx::http::Error;
use kayrx::service::{Service, ServiceFactory};
use futures::future::{FutureExt, LocalBoxFuture};

pub(crate) type BoxedHttpService<Req> = Box<
    dyn Service<
        Request = Req,
        Response = (),
        Error = Error,
        Future = LocalBoxFuture<'static, Result<(), Error>>,
    >,
>;

pub(crate) type BoxedHttpNewService<Req> = Box<
    dyn ServiceFactory<
        Config = (),
        Request = Req,
        Response = (),
        Error = Error,
        InitError = (),
        Service = BoxedHttpService<Req>,
        Future = LocalBoxFuture<'static, Result<BoxedHttpService<Req>, ()>>,
    >,
>;

pub(crate) struct HttpNewService<T: ServiceFactory>(T);

impl<T> HttpNewService<T>
where
    T: ServiceFactory<Response = (), Error = Error>,
    T::Response: 'static,
    T::Future: 'static,
    T::Service: Service<Future = LocalBoxFuture<'static, Result<(), Error>>> + 'static,
    <T::Service as Service>::Future: 'static,
{
    pub fn new(service: T) -> Self {
        HttpNewService(service)
    }
}

impl<T> ServiceFactory for HttpNewService<T>
where
    T: ServiceFactory<Config = (), Response = (), Error = Error>,
    T::Request: 'static,
    T::Future: 'static,
    T::Service: Service<Future = LocalBoxFuture<'static, Result<(), Error>>> + 'static,
    <T::Service as Service>::Future: 'static,
{
    type Config = ();
    type Request = T::Request;
    type Response = ();
    type Error = Error;
    type InitError = ();
    type Service = BoxedHttpService<T::Request>;
    type Future = LocalBoxFuture<'static, Result<Self::Service, ()>>;

    fn new_service(&self, _: ()) -> Self::Future {
        let fut = self.0.new_service(());

        async move {
            fut.await.map_err(|_| ()).map(|service| {
                let service: BoxedHttpService<_> =
                    Box::new(HttpServiceWrapper { service });
                service
            })
        }
        .boxed_local()
    }
}

struct HttpServiceWrapper<T: Service> {
    service: T,
}

impl<T> Service for HttpServiceWrapper<T>
where
    T: Service<
        Response = (),
        Future = LocalBoxFuture<'static, Result<(), Error>>,
        Error = Error,
    >,
    T::Request: 'static,
{
    type Request = T::Request;
    type Response = ();
    type Error = Error;
    type Future = LocalBoxFuture<'static, Result<(), Error>>;

    fn poll_ready(&mut self, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
        self.service.poll_ready(cx)
    }

    fn call(&mut self, req: Self::Request) -> Self::Future {
        self.service.call(req)
    }
}