Instead of writing something like:
let hello = get()
.and(path!(String))
.and_then(|string| handlers::hello(string).map_err(warp::reject::custom))
.boxed()
I'd like to be able to write:
let hello = get()
.and(path!(String))
.handle(handlers::hello)
where handle
does the and_then
-> map_err
-> boxed
thing.
Right now I use a set of traits for each arity handler. This is the 2-arity handler:
pub trait Handle2<A, B, Fut, R, F>
where
R: Reject,
F: Fn(A, B) -> Fut,
Fut: Future<Output = Result<String, R>>,
{
fn handle(self, f: F) -> BoxedFilter<(String,)>;
}
impl<A, B, Fut, R, F, T, Futr> Handle2<A, B, Fut, R, F> for T
where
R: Reject,
F: Fn(A, B) -> Fut + Clone + Sync + Send + 'static,
Fut: Future<Output = Result<String, R>> + Send,
Futr: Future<Output = Result<(A, B), Rejection>> + Send,
T: Filter<Extract = (A, B), Error = Rejection, Future = Futr> + Sync + Send + 'static,
{
fn handle(self, f: F) -> BoxedFilter<(String,)> {
self.and_then(move |a, b| f(a, b).map_err(warp::reject::custom))
.boxed()
}
}
It's awesome that you can do this in Rust, but is there a simpler way to achieve this?