warp
warp copied to clipboard
add `tuple_all` filter combinator
Adds a new method to Filter
that wraps Self::Extract
in a tuple. This is useful in generic code that doesn't know how many arguments the filter extracts.
// effective signature:
fn tuple_args(self) -> impl Filter<Extract = (Self::Extract,), Error = Self::Error>
I added an example for documentation, but it's a little complicated, so maybe we should move it to an example or test case, and link to it. Or if someone has a less complicated example, we can use that instead. I'll post it here too:
use warp::{filters::BoxedFilter, Filter, Rejection};
trait FilterExt: Filter {
/// similar to `and_then`, except the closure is run inside of
/// `tokio::spawn_blocking` and may block.
/// Note that, for simplicity, the closure is passed all arguments
/// as a single tuple.
///
/// # Example
///
/// ```
/// let route = warp::path!("posts" / u64)
/// .and(warp::method())
/// .blocking_and_then(|(id, method)| {
/// // do something with id and method. It's safe to block here.
/// });
/// ```
fn blocking_and_then<F, O>(self, func: F) -> BoxedFilter<(O,)>
where
F: Fn(Self::Extract) -> Result<O, Rejection> + Clone + Send + Sync + 'static,
Self: Filter<Error = Rejection> + Clone + Sized + Send + Sync + 'static,
Self::Extract: Send + 'static,
O: Send + 'static,
{
self.tuple_args()
.and_then(move |args| {
let func = func.clone();
async move {
tokio::task::spawn_blocking(move || func(args))
.await
.unwrap_or_else(|err| panic!("{}", err))
}
})
.boxed()
}
}
Note that this is the inverse of untuple_one
.
EDIT: and as far as naming goes, another possible name is tuple_one
. That would make it more obvious that these combinators are the opposites of each other, but I'm not sure that name is quite right. untuple_one
requires there to be one argument that is a tuple, and "untuples it"; this combinator, on the other hand, can have any number of arguments, and combines them into a single argument. I'm OK with any name really, just want to have this so this example works.
@seanmonstar sorry it took me so long to get back to this! I renamed the method from tuple_args
to tuple_all
, because I think the name matches up with untuple_one
better, and replaced the example in the docs with a simpler one based off of the one you gave me.
@seanmonstar just wanted to check on this, let me know if there's any more changes you'd like me to make