1 use std::fmt;
2 use std::future::Future;
3 use std::pin::Pin;
4 use std::sync::Arc;
5 
6 use futures::TryFutureExt;
7 
8 use super::{Filter, FilterBase, Internal, Tuple};
9 use crate::reject::Rejection;
10 
11 /// A type representing a boxed `Filter` trait object.
12 ///
13 /// The filter inside is a dynamic trait object. The purpose of this type is
14 /// to ease returning `Filter`s from other functions.
15 ///
16 /// To create one, call `Filter::boxed` on any filter.
17 ///
18 /// # Examples
19 ///
20 /// ```
21 /// use warp::{Filter, filters::BoxedFilter, Reply};
22 ///
23 /// pub fn assets_filter() -> BoxedFilter<(impl Reply,)> {
24 ///     warp::path("assets")
25 ///         .and(warp::fs::dir("./assets"))
26 ///         .boxed()
27 /// }
28 /// ```
29 ///
30 pub struct BoxedFilter<T: Tuple> {
31     filter: Arc<
32         dyn Filter<
33                 Extract = T,
34                 Error = Rejection,
35                 Future = Pin<Box<dyn Future<Output = Result<T, Rejection>> + Send>>,
36             > + Send
37             + Sync,
38     >,
39 }
40 
41 impl<T: Tuple + Send> BoxedFilter<T> {
new<F>(filter: F) -> BoxedFilter<T> where F: Filter<Extract = T> + Send + Sync + 'static, F::Error: Into<Rejection>,42     pub(super) fn new<F>(filter: F) -> BoxedFilter<T>
43     where
44         F: Filter<Extract = T> + Send + Sync + 'static,
45         F::Error: Into<Rejection>,
46     {
47         BoxedFilter {
48             filter: Arc::new(BoxingFilter {
49                 filter: filter.map_err(super::Internal, Into::into),
50             }),
51         }
52     }
53 }
54 
55 impl<T: Tuple> Clone for BoxedFilter<T> {
clone(&self) -> BoxedFilter<T>56     fn clone(&self) -> BoxedFilter<T> {
57         BoxedFilter {
58             filter: self.filter.clone(),
59         }
60     }
61 }
62 
63 impl<T: Tuple> fmt::Debug for BoxedFilter<T> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result64     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
65         f.debug_struct("BoxedFilter").finish()
66     }
67 }
68 
_assert_send()69 fn _assert_send() {
70     fn _assert<T: Send>() {}
71     _assert::<BoxedFilter<()>>();
72 }
73 
74 impl<T: Tuple + Send> FilterBase for BoxedFilter<T> {
75     type Extract = T;
76     type Error = Rejection;
77     type Future = Pin<Box<dyn Future<Output = Result<T, Rejection>> + Send>>;
78 
filter(&self, _: Internal) -> Self::Future79     fn filter(&self, _: Internal) -> Self::Future {
80         self.filter.filter(Internal)
81     }
82 }
83 
84 struct BoxingFilter<F> {
85     filter: F,
86 }
87 
88 impl<F> FilterBase for BoxingFilter<F>
89 where
90     F: Filter,
91     F::Future: Send + 'static,
92 {
93     type Extract = F::Extract;
94     type Error = F::Error;
95     type Future = Pin<Box<dyn Future<Output = Result<Self::Extract, Self::Error>> + Send>>;
96 
filter(&self, _: Internal) -> Self::Future97     fn filter(&self, _: Internal) -> Self::Future {
98         Box::pin(self.filter.filter(Internal).into_future())
99     }
100 }
101