//! `IoHandler` middlewares use calls::Metadata; use types::{Request, Response}; use futures::Future; /// RPC middleware pub trait Middleware: Send + Sync + 'static { /// A returned future. type Future: Future, Error=()> + Send + 'static; /// Method invoked on each request. /// Allows you to either respond directly (without executing RPC call) /// or do any additional work before and/or after processing the request. fn on_request(&self, request: Request, meta: M, next: F) -> Self::Future where F: FnOnce(Request, M) -> X + Send, X: Future, Error=()> + Send + 'static; } /// No-op middleware implementation #[derive(Debug, Default)] pub struct Noop; impl Middleware for Noop { type Future = Box, Error=()> + Send>; fn on_request(&self, request: Request, meta: M, process: F) -> Self::Future where F: FnOnce(Request, M) -> X + Send, X: Future, Error=()> + Send + 'static, { Box::new(process(request, meta)) } } impl, B: Middleware> Middleware for (A, B) { type Future = A::Future; fn on_request(&self, request: Request, meta: M, process: F) -> Self::Future where F: FnOnce(Request, M) -> X + Send, X: Future, Error=()> + Send + 'static, { self.0.on_request(request, meta, move |request, meta| { self.1.on_request(request, meta, process) }) } } impl, B: Middleware, C: Middleware> Middleware for (A, B, C) { type Future = A::Future; fn on_request(&self, request: Request, meta: M, process: F) -> Self::Future where F: FnOnce(Request, M) -> X + Send, X: Future, Error=()> + Send + 'static, { self.0.on_request(request, meta, move |request, meta| { self.1.on_request(request, meta, move |request, meta| { self.2.on_request(request, meta, process) }) }) } } impl, B: Middleware, C: Middleware, D: Middleware> Middleware for (A, B, C, D) { type Future = A::Future; fn on_request(&self, request: Request, meta: M, process: F) -> Self::Future where F: FnOnce(Request, M) -> X + Send, X: Future, Error=()> + Send + 'static, { self.0.on_request(request, meta, move |request, meta| { self.1.on_request(request, meta, move |request, meta| { self.2.on_request(request, meta, move |request, meta| { self.3.on_request(request, meta, process) }) }) }) } }