I'm getting the following error,
error[E0283]: type annotations needed for `warp::filter::and_then::AndThen<warp::filter::and::And<warp::filter::and::And<impl warp::Filter+std::marker::Copy, impl warp::Filte
r+std::marker::Copy>, impl warp::Filter+std::marker::Copy>, [closure@src/http.rs:12:13: 24:4]>`
--> src/http.rs:12:4
|
9 | let create_user = warp::post()
| ----------- consider giving `create_user` the explicit type `warp::filter::and_then::AndThen<warp::filter::and::And<warp::filter::and::And<impl warp::Filter+std:
:marker::Copy, impl warp::Filter+std::marker::Copy>, impl warp::Filter+std::marker::Copy>, [closure@src/http.rs:12:13: 24:4]>`, with the type parameters specified
...
12 | .and_then(|user: super::user::User| async move {
| ^^^^^^^^ cannot infer type
|
= note: cannot satisfy `_: reject::sealed::CombineRejection<Rejection>`
This is what I wrote. I'm confused at how this is supposed to look,
pub async fn users() -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
let create_user = warp::post()
.and(warp::path::end())
.and(warp::body::json())
.and_then(|user: super::user::User| async move {
match &user.id_user {
None => {
if let Ok(u) = user.insert().await {
Ok(warp::reply::json(&u))
}
else {
Ok(warp::reply::json(&"FOO".to_owned()))
}
}
Some(_) => Ok(warp::reply::json(&"FOO".to_owned())),
}
});
let routes = warp::path("users");
routes.and(create_user)
}
How is this supposed to look, am I really supposed to use an explicit type like,
warp::filter::and_then::AndThen<warp::filter::and::And<warp::filter::and::And<impl warp::Filter+std::marker::Copy, impl warp::Filter+std::marker::Copy>, impl warp::Filter+std::marker::Copy>
Just to be clear what I want here, is a create user end point.
&user.insert()
will insert the user object in the database, and return a new user object with the ID.How can I make sense of the absurdly complex type annotations that Warp is requesting? Is this really required, or am I making mistake?
The issue here is failing type inference for the async block in the and_then()
closure. There is no Err()
path which would tell the compiler what the Error
variant would be, thus the inference fails. You can fix this by annotating the full Result
type on one of the return branches:
Ok::<_, warp::Rejection>(warp::reply::json(&u))
For additional reference:
https://users.rust-lang.org/t/async-function-parameter-results-in-type-annotation-error/45379
and a workaround for similar issue about using ?
in async blocks:
https://rust-lang.github.io/async-book/07_workarounds/02_err_in_async_blocks.html