Difficult to use closure as middleware
- Dominant language
- Rust
- Stars
- 1.5k
- Forks
- 128
- PR merge metrics
- No merged PRs in 30d
Description
You can't trivially set a closure as a middleware on a request even though closures implement `Middleware`; the obvious doesn't work by itself:
```rust
surf::post(...)
.middleware(|request, client, next| { // error on `next`: type annotation needed
// I want to log the full request, the logger middleware doesn't print much
trace!("request {:?}", request);
next.run(request, client)
})
...
```
However, because the concrete `HttpClient` types are not importable, there's no way to give a type for `Next` that satisfies the compiler:
```rust
.middleware(|request, client, next: Next<'_, /* what the heck do I put here? `impl HttpClient` isn't allowed */> | { .. })
```
It's not too difficult to write a function that allows you to omit the type annotation, but it's not the greatest experience:
```rust
fn apply_middleware_fn(request: surf::Request, middleware: F) -> surf::Request
where F: Send + Sync + 'static + for<'a> Fn(Request, C, Next<'a, C>) -> BoxFuture<'a, Result>
{
request.middleware(middleware)
}
apply_middleware_fn(request, |request, client, next| { ... });
```
This could be fixed pretty simply by providing this wrapper as a method on `Request`:
```rust
impl Request {
pub fn middleware_fn(self, middleware_fn: F) -> Self
where F: Send + Sync + 'static + for<'a> Fn(Request, C, Next<'a, C>) -> BoxFuture<'a, Result>
{
self.middleware(middleware_fn)
}
}
```
This should allow the above usage to work as-is without naming types in the closure.
Contributor guide
Assessment
This issue has not been assessed yet.