tower_async/filter/
predicate.rs

1use futures_core::Future;
2use futures_util::TryFutureExt;
3
4use crate::BoxError;
5
6/// Checks a request asynchronously.
7pub trait AsyncPredicate<Request> {
8    /// The type of requests returned by [`check`].
9    ///
10    /// This request is forwarded to the inner service if the predicate
11    /// succeeds.
12    ///
13    /// [`check`]: crate::filter::AsyncPredicate::check
14    type Request;
15
16    /// Check whether the given request should be forwarded.
17    ///
18    /// If the future resolves with [`Ok`], the request is forwarded to the inner service.
19    fn check(
20        &self,
21        request: Request,
22    ) -> impl std::future::Future<Output = Result<Self::Request, BoxError>>;
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(&self, request: Request) -> Result<Self::Request, BoxError>;
38}
39
40impl<F, T, U, R, E> AsyncPredicate<T> for F
41where
42    F: Fn(T) -> U,
43    U: Future<Output = Result<R, E>>,
44    E: Into<BoxError>,
45{
46    type Request = R;
47
48    async fn check(&self, request: T) -> Result<Self::Request, BoxError> {
49        self(request).err_into().await
50    }
51}
52
53impl<F, T, R, E> Predicate<T> for F
54where
55    F: Fn(T) -> Result<R, E>,
56    E: Into<BoxError>,
57{
58    type Request = R;
59
60    fn check(&self, request: T) -> Result<Self::Request, BoxError> {
61        self(request).map_err(Into::into)
62    }
63}