tower/filter/
predicate.rs

1use crate::BoxError;
2use std::future::Future;
3
4/// Checks a request asynchronously.
5pub 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.
22    fn check(&mut self, request: Request) -> Self::Future;
23}
24/// Checks a request synchronously.
25pub 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.
37    fn check(&mut self, request: Request) -> Result<Self::Request, BoxError>;
38}
39
40impl<F, T, U, R, E> AsyncPredicate<T> for F
41where
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
49    fn check(&mut self, request: T) -> Self::Future {
50        use futures_util::TryFutureExt;
51        self(request).err_into()
52    }
53}
54
55impl<F, T, R, E> Predicate<T> for F
56where
57    F: FnMut(T) -> Result<R, E>,
58    E: Into<BoxError>,
59{
60    type Request = R;
61
62    fn check(&mut self, request: T) -> Result<Self::Request, BoxError> {
63        self(request).map_err(Into::into)
64    }
65}