1 use crate::BoxError; 2 use std::future::Future; 3 4 /// Checks a request asynchronously. 5 pub trait AsyncPredicate<Request> { 6 /// The future returned by [`check`]. 7 /// 8 /// [`check`]: crate::filter::AsyncPredicate::check 9 type Future: Future<Output = Result<Self::Request, BoxError>>; 10 11 /// The type of requests returned by [`check`]. 12 /// 13 /// This request is forwarded to the inner service if the predicate 14 /// succeeds. 15 /// 16 /// [`check`]: crate::filter::AsyncPredicate::check 17 type Request; 18 19 /// Check whether the given request should be forwarded. 20 /// 21 /// If the future resolves with [`Ok`], the request is forwarded to the inner service. check(&mut self, request: Request) -> Self::Future22 fn check(&mut self, request: Request) -> Self::Future; 23 } 24 /// Checks a request synchronously. 25 pub trait Predicate<Request> { 26 /// The type of requests returned by [`check`]. 27 /// 28 /// This request is forwarded to the inner service if the predicate 29 /// succeeds. 30 /// 31 /// [`check`]: crate::filter::Predicate::check 32 type Request; 33 34 /// Check whether the given request should be forwarded. 35 /// 36 /// If the future resolves with [`Ok`], the request is forwarded to the inner service. check(&mut self, request: Request) -> Result<Self::Request, BoxError>37 fn check(&mut self, request: Request) -> Result<Self::Request, BoxError>; 38 } 39 40 impl<F, T, U, R, E> AsyncPredicate<T> for F 41 where 42 F: FnMut(T) -> U, 43 U: Future<Output = Result<R, E>>, 44 E: Into<BoxError>, 45 { 46 type Future = futures_util::future::ErrInto<U, BoxError>; 47 type Request = R; 48 check(&mut self, request: T) -> Self::Future49 fn check(&mut self, request: T) -> Self::Future { 50 use futures_util::TryFutureExt; 51 self(request).err_into() 52 } 53 } 54 55 impl<F, T, R, E> Predicate<T> for F 56 where 57 F: FnMut(T) -> Result<R, E>, 58 E: Into<BoxError>, 59 { 60 type Request = R; 61 check(&mut self, request: T) -> Result<Self::Request, BoxError>62 fn check(&mut self, request: T) -> Result<Self::Request, BoxError> { 63 self(request).map_err(Into::into) 64 } 65 } 66