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