titan 0.4.2

Titan is a web-framework, SSR engine with css-in-rust support, http server and http router.
Documentation
use std::{future::Future, marker::PhantomData, pin::Pin, task::Poll};

use titan_core::{FromRequest, Handler, Respondable};
use titan_http::{Request, Response};

pub struct Route<T, Args>
where
  T: Handler<Args>,
  Args: FromRequest,
{
  handler: T,
  _a: PhantomData<Args>,
}

impl<T, A> Clone for Route<T, A>
where
  T: Handler<A> + Clone,
  A: FromRequest,
{
  fn clone(&self) -> Self {
    Self { _a: PhantomData, handler: self.handler.clone() }
  }
}

impl<T, Args> Route<T, Args>
where
  T: Handler<Args>,
  Args: FromRequest + Send + 'static,
{
  pub fn new(handler: T) -> Self {
    Self { handler, _a: PhantomData }
  }
}

impl<T, Args> titan_core::Service<Request> for Route<T, Args>
where
  T: Handler<Args> + Sync + Clone + 'static,
  T::Future: Future<Output = T::Output> + Send + 'static,
  T::Output: Respondable,
  Args: FromRequest + Send + Sync + 'static,
  Args::Error: Send,
{
  type Response = Response;
  type Error = Response;
  type Future =
    Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;

  fn poll_ready(
    &mut self,
    _cx: &mut std::task::Context<'_>,
  ) -> Poll<Result<(), Self::Error>> {
    Poll::Ready(Ok(()))
  }

  fn call(&mut self, req: Request) -> Self::Future {
    let handler = self.handler.clone();
    Box::pin(async move {
      let response: Result<Args, <Args as FromRequest>::Error> =
        FromRequest::from_request(req);
      match response {
        Ok(value) => {
          let result = Handler::call(&handler, value).await;
          Ok(result.respond())
        }
        Err(_err) => Err(_err.respond()),
      }
    })
  }
}