Как выполнить централизованную обработку ошибок для конвейерного вызова метода в Rust? - PullRequest
0 голосов
/ 24 апреля 2020

Я хочу выполнить синтаксический анализ json и сохранить результат в наборе Ха sh. Я хочу использовать iter (), например:

let my_json_list = vec!("{\"name\":\"Tim\", \"age\":18}", "{\"name\":\"Alex\", \"age\":25}")
let mut my_hash_set::HashSet<String> = HashSet::new();
my_hash_set.extend(
            my_json_list.iter()
                        .map(|str| serde_json::from_str(str)) // return Result
                        .map(|json| json.pointer("/name") // return Option
                        .when_err_or_none(|err| skip();) // handle Err and None, not extend the map
                        .map(|key| key.as_str().unwrap().to_owned())
) 

Возможно ли это?

Ответы [ 2 ]

0 голосов
/ 24 апреля 2020

Я думаю, что в этом случае я бы определил выделенное struct Person, и пусть serde выполняет тяжелую работу:

use serde_json; // 1.0.48
use serde; // 1.0.104

use serde::Deserialize;
use std::collections::HashSet;

#[derive(Deserialize)]
struct Person {
    name: String,
    age: usize,
}

fn main() {
    let my_json_list = vec!(
        "{\"name\":\"Tim\", \"age\":18}",
        "{\"name\":\"Alex\", \"age\":25}"
    );
    let my_hash_set : HashSet<String> = my_json_list
        .iter()
        .filter_map(|str| serde_json::from_str::<Person>(str)
            .ok() // convert Result -> Option
            .map(|person| person.name) // only interested in name
        )
        .collect(); // collect names into HashSet
}

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=607cfe125b5690fb89b23ca904da31cc

Если вы предпочитаете более ad-ho c решение без структуры: используйте serde_json; // 1.0.48

use std::collections::HashSet;

fn main() {
    let my_json_list = vec!(
        "{\"name\":\"Tim\", \"age\":18}",
        "{\"name\":\"Alex\", \"age\":25}"
    );
    let my_hash_set : HashSet<String> = my_json_list
        .iter()
        .filter_map(|str| serde_json::from_str::<serde_json::Value>(str)
            .ok() // convert Result -> Option
            .and_then(|json_val| json_val.get("name")
                .and_then(|name_val| name_val.as_str()) // try to convert to &str
                .map(|str| str.to_string()) // convert &str to String
            )
        )
        .collect(); // collect names into HashSet
}

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=607cfe125b5690fb89b23ca904da31cc

0 голосов
/ 24 апреля 2020
let my_json_list = vec![
    "{\"name\":\"Tim\", \"age\":18}",
    "{\"name\":\"Alex\", \"age\":25}",
];
let mut my_hash_set: HashSet<String> = HashSet::new();
my_hash_set.extend(
    my_json_list
        .iter()
        .map(|str| serde_json::from_str::<Value>(str))
        .filter(|result| result.is_ok())
        .map(|result| result.unwrap())
        .filter(|json| json["name"].is_string())
        .map(|json| json["name"].as_str().unwrap().to_string()),
);

Это то, что вы хотите?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...