[−][src]Trait roa::Middleware
Middleware
There are two kinds of middlewares, the one is functional middlewares, the another is trait middlewares.
Normal Functional Middlewares
A normal functional middleware is an object implements Fn
trait:
use roa_core::{Context, Next, Result, State, Middleware}; use std::future::Future; fn is_normal<S, F>( middleware: impl 'static + Send + Sync + Fn(Context<S>, Next) -> F ) -> impl Middleware<S> where S: State, F: 'static + Future<Output=Result> { middleware } is_normal(|_ctx: Context<()>, next| next);
Both of function pointers and closures are middlewares:
use roa_core::{Middleware, Context, Next, Result, State}; fn is_middleware<S: State>(_: impl Middleware<S>) {} async fn function_ptr(_ctx: Context<()>, next: Next) -> Result { next.await } // capture a variable to avoid matching lambda as function pointer. let x = 0; // moving is necessary to confirm closure is static. let closure = move |ctx: Context<()>, next: Next| async move { let x = x; next.await }; is_middleware(function_ptr); is_middleware(closure);
Endpoints
Another kind of functional middlewares is endpoints,
whose type is fn<S, F>(Context<S>) -> F where F: 'static + Send + Future<Output=Result>
.
Endpoints never invoke next middleware.
use roa_core::{Middleware, Context, Result, State}; use std::future::Future; fn is_middleware<S: State>(_: impl Middleware<S>) {} async fn endpoint(_: Context<()>) -> Result { Ok(()) } // `fn(Context<()>) -> impl 'static + Send + Future<Output=Result>` is a function pointer // which returns value of a existential type. // // `fn<F>(Context<()>) -> F where F: 'static + Send + Future<Output=Result>` is a template. // // They are different! // // is_middleware(endpoint); compile fails! fn to_middleware<F>(middleware: fn(Context<()>) -> F) -> impl Middleware<()> where F: 'static + Future<Output=Result> { middleware } is_middleware(to_middleware(endpoint))
Trait Middlewares
A trait middleware is an object implementing trait Middleware
.
use roa_core::{State, Middleware, Context, Next, Result, async_trait}; use async_std::sync::Arc; use std::time::Instant; fn is_middleware(_: impl Middleware<()>) {} struct Logger; #[async_trait(?Send)] impl <S: State> Middleware<S> for Logger { async fn handle(self:Arc<Self>, ctx: Context<S>, next: Next) -> Result { let start = Instant::now(); let result = next.await; println!("time elapsed: {}ms", start.elapsed().as_millis()); result } } is_middleware(Logger);
Required methods
fn handle<'async_trait>(
self: Arc<Self>,
ctx: Context<S>,
next: Pin<Box<dyn Future<Output = Result<(), Error>> + 'static>>
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + 'async_trait>> where
Self: 'async_trait,
self: Arc<Self>,
ctx: Context<S>,
next: Pin<Box<dyn Future<Output = Result<(), Error>> + 'static>>
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + 'async_trait>> where
Self: 'async_trait,
Handle context and next, then return a future to get status.
Provided methods
fn end<'async_trait>(
self: Arc<Self>,
ctx: Context<S>
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + 'async_trait>> where
Self: 'async_trait,
self: Arc<Self>,
ctx: Context<S>
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + 'async_trait>> where
Self: 'async_trait,
Handle context as an endpoint.
Implementations on Foreign Types
impl<S, F> Middleware<S> for fn(Context<S>) -> F where
F: 'static + Future<Output = Result<(), Error>>,
S: State,
[src]
F: 'static + Future<Output = Result<(), Error>>,
S: State,
fn handle<'async_trait>(
self: Arc<fn(Context<S>) -> F>,
ctx: Context<S>,
_next: Pin<Box<dyn Future<Output = Result<(), Error>> + 'static>>
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + 'async_trait>> where
fn(Context<S>) -> F: 'async_trait,
[src]
self: Arc<fn(Context<S>) -> F>,
ctx: Context<S>,
_next: Pin<Box<dyn Future<Output = Result<(), Error>> + 'static>>
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + 'async_trait>> where
fn(Context<S>) -> F: 'async_trait,
impl<S> Middleware<S> for RouteEndpoint<S> where
S: State,
S: State,
fn handle<'async_trait>(
self: Arc<RouteEndpoint<S>>,
ctx: Context<S>,
_next: Pin<Box<dyn Future<Output = Result<(), Error>> + 'static>>
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + 'async_trait>> where
RouteEndpoint<S>: 'async_trait,
self: Arc<RouteEndpoint<S>>,
ctx: Context<S>,
_next: Pin<Box<dyn Future<Output = Result<(), Error>> + 'static>>
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + 'async_trait>> where
RouteEndpoint<S>: 'async_trait,
impl<F, S, Fut> Middleware<S> for Websocket<F, S, Fut> where
F: 'static + Sync + Send + Fn(SyncContext<S>, WebSocketStream<Upgraded>) -> Fut,
Fut: 'static + Send + Future<Output = ()>,
S: State,
F: 'static + Sync + Send + Fn(SyncContext<S>, WebSocketStream<Upgraded>) -> Fut,
Fut: 'static + Send + Future<Output = ()>,
S: State,
fn handle<'async_trait>(
self: Arc<Websocket<F, S, Fut>>,
ctx: Context<S>,
_next: Pin<Box<dyn Future<Output = Result<(), Error>> + 'static>>
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + 'async_trait>> where
Websocket<F, S, Fut>: 'async_trait,
self: Arc<Websocket<F, S, Fut>>,
ctx: Context<S>,
_next: Pin<Box<dyn Future<Output = Result<(), Error>> + 'static>>
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + 'async_trait>> where
Websocket<F, S, Fut>: 'async_trait,
Implementors
impl<S, F, T> Middleware<S> for T where
F: 'static + Future<Output = Result<(), Error>>,
S: State,
T: 'static + Sync + Send + Fn(Context<S>, Pin<Box<dyn Future<Output = Result<(), Error>> + 'static>>) -> F,
[src]
F: 'static + Future<Output = Result<(), Error>>,
S: State,
T: 'static + Sync + Send + Fn(Context<S>, Pin<Box<dyn Future<Output = Result<(), Error>> + 'static>>) -> F,
fn handle<'async_trait>(
self: Arc<T>,
ctx: Context<S>,
next: Pin<Box<dyn Future<Output = Result<(), Error>> + 'static>>
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + 'async_trait>> where
T: 'async_trait,
[src]
self: Arc<T>,
ctx: Context<S>,
next: Pin<Box<dyn Future<Output = Result<(), Error>> + 'static>>
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + 'async_trait>> where
T: 'async_trait,
impl<S: State> Middleware<S> for Compress
[src]
fn handle<'async_trait>(
self: Arc<Self>,
ctx: Context<S>,
next: Next
) -> Pin<Box<dyn Future<Output = Result> + 'async_trait>> where
Self: 'async_trait,
[src]
self: Arc<Self>,
ctx: Context<S>,
next: Next
) -> Pin<Box<dyn Future<Output = Result> + 'async_trait>> where
Self: 'async_trait,