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}