Actix-Web:将消息发送到数据库处理程序,有条件地将消息发送到第二个处理程序

时间:2019-01-12 23:04:29

标签: rust rust-diesel rust-actix

我正在尝试向一个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中完成此任务?

1 个答案:

答案 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转换为futurefuture::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