Skip to content

Commit

Permalink
feat(core): improve handlers and add ServiceHandler (#117)
Browse files Browse the repository at this point in the history
  • Loading branch information
fundon authored Dec 16, 2023
1 parent 68d5dc5 commit 89d7208
Show file tree
Hide file tree
Showing 15 changed files with 104 additions and 28 deletions.
36 changes: 27 additions & 9 deletions viz-core/src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ pub use or_else::OrElse;
mod transform;
pub use transform::Transform;

mod service;
pub use service::ServiceHandler;

/// A simplified asynchronous interface for handling input and output.
///
/// Composable request handlers.
Expand Down Expand Up @@ -83,14 +86,6 @@ where
/// [`FutureExt`]: https://docs.rs/futures/latest/futures/future/trait.FutureExt.html
/// [`StreamExt`]: https://docs.rs/futures/latest/futures/stream/trait.StreamExt.html
pub trait HandlerExt<I>: Handler<I> {
/// Converts this Handler into a [`BoxHandler`].
fn boxed(self) -> BoxHandler<I, Self::Output>
where
Self: Sized,
{
Box::new(self)
}

/// Maps the input before the handler calls.
fn before<F>(self, f: F) -> Before<Self, F>
where
Expand All @@ -115,6 +110,21 @@ pub trait HandlerExt<I>: Handler<I> {
Around::new(self, f)
}

/// Wraps this handler in an Either handler, making it the left-hand variant of that Either.
///
/// Returns the left-hand variant if `enable` is true, otherwise returns the right-hand
/// variant.
fn either<R>(self, r: R, enable: bool) -> Either<Self, R>
where
Self: Sized,
{
if enable {
Either::Left(self)
} else {
Either::Right(r)
}
}

/// Maps the `Ok` value of the output if after the handler called.
fn map<F>(self, f: F) -> Map<Self, F>
where
Expand Down Expand Up @@ -173,7 +183,15 @@ pub trait HandlerExt<I>: Handler<I> {
CatchUnwind::new(self, f)
}

/// Returns a new [Handler] that wrapping the `Self` and a type implementing [`Transform`].
/// Converts this Handler into a [`BoxHandler`].
fn boxed(self) -> BoxHandler<I, Self::Output>
where
Self: Sized,
{
Box::new(self)
}

/// Returns a new [`Handler`] that wrapping the `Self` and a type implementing [`Transform`].
fn with<T>(self, t: T) -> T::Output
where
T: Transform<Self>,
Expand Down
3 changes: 2 additions & 1 deletion viz-core/src/handler/after.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ pub struct After<H, F> {
}

impl<H, F> After<H, F> {
/// Creates an [`After`] handler.
#[inline]
pub(super) fn new(h: H, f: F) -> Self {
pub fn new(h: H, f: F) -> Self {
Self { h, f }
}
}
Expand Down
3 changes: 2 additions & 1 deletion viz-core/src/handler/and_then.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ pub struct AndThen<H, F> {
}

impl<H, F> AndThen<H, F> {
/// Creates an [`AndThen`] handler.
#[inline]
pub(super) fn new(h: H, f: F) -> Self {
pub fn new(h: H, f: F) -> Self {
Self { h, f }
}
}
Expand Down
3 changes: 2 additions & 1 deletion viz-core/src/handler/around.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ pub struct Around<H, F> {
}

impl<H, F> Around<H, F> {
/// Creates an [`Around`] handler.
#[inline]
pub(super) fn new(h: H, f: F) -> Self {
pub fn new(h: H, f: F) -> Self {
Self { h, f }
}
}
Expand Down
3 changes: 2 additions & 1 deletion viz-core/src/handler/before.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ pub struct Before<H, F> {
}

impl<H, F> Before<H, F> {
/// Creates a [`Before`] handler.
#[inline]
pub(super) fn new(h: H, f: F) -> Self {
pub fn new(h: H, f: F) -> Self {
Self { h, f }
}
}
Expand Down
3 changes: 2 additions & 1 deletion viz-core/src/handler/catch_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ where
}

impl<H, F, R, E> CatchError<H, F, R, E> {
/// Creates a [`CatchError`] handler.
#[inline]
pub(super) fn new(h: H, f: F) -> Self {
pub fn new(h: H, f: F) -> Self {
Self {
h,
f,
Expand Down
5 changes: 3 additions & 2 deletions viz-core/src/handler/catch_unwind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ pub struct CatchUnwind<H, F> {
}

impl<H, F> CatchUnwind<H, F> {
/// Creates an [`CatchUnwind`] handler.
#[inline]
pub(super) fn new(h: H, f: F) -> Self {
pub fn new(h: H, f: F) -> Self {
Self { h, f }
}
}
Expand All @@ -22,8 +23,8 @@ impl<H, F> CatchUnwind<H, F> {
impl<H, F, I, O, R> Handler<I> for CatchUnwind<H, F>
where
I: Send + 'static,
O: IntoResponse + Send,
H: Handler<I, Output = Result<O>> + Clone,
O: IntoResponse + Send,
F: Handler<Box<dyn Any + Send>, Output = R> + Clone,
R: IntoResponse,
{
Expand Down
7 changes: 4 additions & 3 deletions viz-core/src/handler/either.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ where
type Output = O;

async fn call(&self, i: I) -> Self::Output {
match self {
Self::Left(l) => l.call(i).await,
Self::Right(r) => r.call(i).await,
match &self {
Self::Left(l) => l.call(i),
Self::Right(r) => r.call(i),
}
.await
}
}
4 changes: 2 additions & 2 deletions viz-core/src/handler/fn_ext_hanlder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ where
}

impl<H, E, O> FnExtHandler<H, E, O> {
/// Create a new `Handler` for the extractors.
pub(super) fn new(h: H) -> Self {
/// Creates a new `Handler` for the extractors.
pub fn new(h: H) -> Self {
Self(h, PhantomData)
}
}
Expand Down
4 changes: 2 additions & 2 deletions viz-core/src/handler/into_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ use crate::{FromRequest, IntoResponse, Request, Result};

use super::{FnExt, FnExtHandler, Handler};

/// Trait implemented by types that can be converted to a [`Handler`].
/// The trait implemented by types that can be converted to a [`Handler`].
pub trait IntoHandler<E, I> {
/// The target handler.
type Handler: Handler<I>;

/// Convert self to a [Handler].
/// Converts self to a [`Handler`].
#[must_use]
fn into_handler(self) -> Self::Handler;
}
Expand Down
3 changes: 2 additions & 1 deletion viz-core/src/handler/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ pub struct Map<H, F> {
}

impl<H, F> Map<H, F> {
/// Creates a [`Map`] handler.
#[inline]
pub(super) fn new(h: H, f: F) -> Self {
pub fn new(h: H, f: F) -> Self {
Self { h, f }
}
}
Expand Down
3 changes: 2 additions & 1 deletion viz-core/src/handler/map_err.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ pub struct MapErr<H, F> {
}

impl<H, F> MapErr<H, F> {
/// Creates a [`MapErr`] handler.
#[inline]
pub(super) fn new(h: H, f: F) -> Self {
pub fn new(h: H, f: F) -> Self {
Self { h, f }
}
}
Expand Down
4 changes: 2 additions & 2 deletions viz-core/src/handler/map_into_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ use crate::{async_trait, Handler, IntoResponse, Response, Result};
pub struct MapInToResponse<H>(pub(crate) H);

impl<H> MapInToResponse<H> {
/// Creates a new `Responder`.
/// Creates a [`MapInToResponse`] handler.
#[inline]
pub(super) fn new(h: H) -> Self {
pub fn new(h: H) -> Self {
Self(h)
}
}
Expand Down
3 changes: 2 additions & 1 deletion viz-core/src/handler/or_else.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ pub struct OrElse<H, F> {
}

impl<H, F> OrElse<H, F> {
/// Creates an [`OrElse`] handler.
#[inline]
pub(super) fn new(h: H, f: F) -> Self {
pub fn new(h: H, f: F) -> Self {
Self { h, f }
}
}
Expand Down
48 changes: 48 additions & 0 deletions viz-core/src/handler/service.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
use http_body_util::BodyExt;
use hyper::service::Service;

use crate::{async_trait, Body, Bytes, Error, Handler, Request, Response, Result};

/// Converts a hyper [`Service`] to a viz [`Handler`].
#[derive(Debug, Clone)]
pub struct ServiceHandler<S> {
s: S,
}

impl<S> ServiceHandler<S> {
/// Creates a new [`ServiceHandler`].
pub fn new(s: S) -> Self {
Self { s }
}
}

#[async_trait]
impl<I, O, S> Handler<Request<I>> for ServiceHandler<S>
where
I: Body + Send + Unpin + 'static,
// O: Body + Send + 'static,
O: Body + Send + Sync + 'static,
O::Data: Into<Bytes>,
O::Error: Into<Error>,
S: Service<Request<I>, Response = Response<O>> + Send + Sync + Clone + 'static,
S::Future: Send,
S::Error: Into<Error>,
{
type Output = Result<Response>;

async fn call(&self, req: Request<I>) -> Self::Output {
self.s
.call(req)
.await
.map(|resp| {
resp.map(|body| {
body.map_frame(|f| f.map_data(Into::into))
.map_err(Into::into)
// .boxed_unsync()
.boxed()
})
.map(Into::into)
})
.map_err(Into::into)
}
}

0 comments on commit 89d7208

Please sign in to comment.