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}