1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
//! Traits and types for handling an HTTP.
#![allow(clippy::module_name_repetitions)]
use crate::{async_trait, Future};
mod after;
mod and_then;
mod around;
mod before;
mod boxed;
mod catch_error;
mod catch_unwind;
mod either;
mod fn_ext;
mod fn_ext_hanlder;
mod into_handler;
mod map;
mod map_err;
mod map_into_response;
mod or_else;
mod transform;
pub use after::After;
pub use and_then::AndThen;
pub use around::{Around, Next};
pub use before::Before;
pub use boxed::BoxHandler;
pub use catch_error::CatchError;
pub use catch_unwind::CatchUnwind;
pub use either::Either;
pub use fn_ext::FnExt;
pub use fn_ext_hanlder::FnExtHandler;
pub use into_handler::IntoHandler;
pub use map::Map;
pub use map_err::MapErr;
pub use map_into_response::MapInToResponse;
pub use or_else::OrElse;
pub use transform::Transform;
/// A simplified asynchronous interface for handling input and output.
///
/// Composable request handlers.
#[async_trait]
pub trait Handler<Input>: dyn_clone::DynClone + Send + Sync + 'static {
/// The returned type after the call operator is used.
type Output;
/// Performs the call operation.
#[must_use]
async fn call(&self, input: Input) -> Self::Output;
}
impl<I, T> HandlerExt<I> for T where T: Handler<I> + ?Sized {}
#[async_trait]
impl<F, I, Fut, O> Handler<I> for F
where
I: Send + 'static,
F: Fn(I) -> Fut + ?Sized + Clone + Send + Sync + 'static,
Fut: Future<Output = O> + Send,
{
type Output = Fut::Output;
async fn call(&self, i: I) -> Self::Output {
(self)(i).await
}
}
/// The [`HandlerExt`] trait, which provides adapters for chaining and composing handlers.
///
/// Likes the [`FutureExt`] and [`StreamExt`] trait.
///
/// [`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
Self: Sized,
{
Before::new(self, f)
}
/// Maps the output `Result<T>` after the handler called.
fn after<F>(self, f: F) -> After<Self, F>
where
Self: Sized,
{
After::new(self, f)
}
/// Wraps around the remaining handler or middleware chain.
fn around<F>(self, f: F) -> Around<Self, F>
where
Self: Sized,
{
Around::new(self, f)
}
/// Maps the `Ok` value of the output if after the handler called.
fn map<F>(self, f: F) -> Map<Self, F>
where
Self: Sized,
{
Map::new(self, f)
}
/// Maps the handler's output type to the [`Response`][crate::Response].
fn map_into_response<O>(self) -> MapInToResponse<Self, O>
where
Self: Sized,
{
MapInToResponse::new(self)
}
/// Calls op if the result is Ok, otherwise returns the Err value of self.
fn and_then<F>(self, f: F) -> AndThen<Self, F>
where
Self: Sized,
{
AndThen::new(self, f)
}
/// Maps the `Err` value of the output if after the handler called.
fn map_err<F>(self, f: F) -> MapErr<Self, F>
where
Self: Sized,
{
MapErr::new(self, f)
}
/// Calls `op` if the output is `Err`, otherwise returns the `Ok` value of the output.
fn or_else<F>(self, f: F) -> OrElse<Self, F>
where
Self: Sized,
{
OrElse::new(self, f)
}
/// Catches rejected error while calling the handler.
fn catch_error<F, R, E>(self, f: F) -> CatchError<Self, F, R, E>
where
Self: Sized,
{
CatchError::new(self, f)
}
/// Catches unwinding panics while calling the handler.
fn catch_unwind<F>(self, f: F) -> CatchUnwind<Self, F>
where
Self: Sized,
{
CatchUnwind::new(self, f)
}
/// 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>,
Self: Sized,
{
t.transform(self)
}
/// Maps the handler.
#[must_use]
fn with_fn<F>(self, f: F) -> Self
where
F: Fn(Self) -> Self,
Self: Sized,
{
f(self)
}
}