我正在尝试向一个db处理程序发送消息,并根据结果向第二个处理程序发送消息,或者从第一个处理程序返回错误。
到目前为止,我提出的建议无效。 rustc说match arms have incompatible types
expected struct 'futures::future::and_then::AndThen', found enum 'std::result::Result'
state
.db
.send(...)
.from_err()
.and_then(|res| match res {
Ok(response) => {
// Do some additional logic here
state
.db
.send(...)
.from_err()
.and_then(|res| match res {
Ok(response) => Ok(HttpResponse::Ok().json(response)),
Err(err) => Ok(HttpResponse::InternalServerError().body(err.to_string()))
})
},
Err(err) => Ok(HttpResponse::InternalServerError().body(err.to_string()))
})
.responder()
问题如何在actix-web中完成此任务?
答案 0 :(得分:2)
你快到了。
使用match
时,所有臂必须产生相同的类型。在您的情况下,一个是与and_then
结合的未来,另一方面,您有一个result
。
此外,除非您的send()
函数返回类型impl Future<Item = Result<R, E>, Error = E>
,否则match
是完全多余的。 and_then
以参数Item
而不是Result<Item, Error>
作为参数。
因此,整个事情可以简化为:
state
.db
.send(...)
.from_err()
.and_then(|res| state.db.send(...).from_err())
.then(|res| match res {
Ok(response) => Ok(HttpResponse::Ok().json(response)),
Err(err) => Ok(HttpResponse::InternalServerError().body(err.to_string()))
})
.responder()
让我们假设您的类型正确。您可以像这样轻松地将Result
转换为future
到future::result
:
state
.db
.send(...)
.from_err()
.and_then(|res| future::result(res).from_err())
.and_then(|res|
// Do some additional logic here
state
.db
.send(...)
.from_err()
)
.and_then(|res| future::result(res).from_err())
.then(|res| match res {
Ok(response) => Ok(HttpResponse::Ok().json(response)),
Err(err) => Ok(HttpResponse::InternalServerError().body(err.to_string()))
})
.responder()
其中的沙箱上有一个示例:https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=6801886b02081160e268f395bcc1ad6c