Соответствует либо Result :: Err, либо необязательному полю внутри Result :: Ok одновременно - PullRequest
0 голосов
/ 28 февраля 2019

У меня есть структура, которая является конечной точкой API, поэтому я не могу изменить ее структуру

struct Response {
    error: Option<String>,
    results: Vec<String>,
}

Если error равно Some, это означает, что произошла ошибка на стороне сервера.

У меня есть функция, которая возвращает структуру:

fn get_results() -> Result<Response, String> {
    unimplemented!()
}

Можно ли сопоставить ошибку get_results Result и необязательный Response.error в той же ветви match?

Это была моя попытка:

fn example() {
    let ret = get_results();
    match ret.map(|resp| resp.error.map_or_else(|| Ok(resp.results), |e| Err(e))) {
        Err(e) => {
            println!("Error: {}", &e);
        }
        Ok(results) => {
            //Handle results
        }
    }
}

Но она не удалась:

error[E0382]: use of moved value: `resp`
  --> src/lib.rs:12:49
   |
12 |     match ret.map(|resp| resp.error.map_or_else(|| Ok(resp.results), |e| Err(e))) {
   |                          ----------             ^^    ---- use occurs due to use in closure
   |                          |                      |
   |                          |                      value used here after move
   |                          value moved here
   |
   = note: move occurs because `resp.error` has type `std::option::Option<std::string::String>`, which does not implement the `Copy` trait

Ответы [ 2 ]

0 голосов
/ 28 февраля 2019

Если поле ошибки является открытым, вы можете сделать что-то вроде этого:

match resp {
    Err(s) | Ok(Response { error: Some(s), .. }) => println!("Error: {}", s),
    Ok(Response { error: None, results }) => println!("Responses: {:?}", results)
}

Это показывает, насколько мощными могут быть операторы сопоставления Rust.

Игровая площадка упрощенного примера

0 голосов
/ 28 февраля 2019

Вы можете преобразовать ответ в результат, подобный этому:

match resp.error {
    Some(e) => Err(e),
    None => Ok(resp.results),
}

Вы можете сгладить вложенный результат с помощью and_then.Вместе это дает:

ret.and_then(|resp| match resp.error {
    Some(e) => Err(e),
    None => Ok(resp.results),
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...