Serde Stream Deserializer для типа, отличного от serde_json::Value

Я хочу проанализировать строку JSON формы

{
    "a": {
        "foo": "bar"
    },
    "b": {
        "foo": "baz"
    }
}

То есть на верхнем уровне есть ряд JSON-объектов, разделенных запятыми. Каждый из этих объектов имеет те же поля, что и другие (т. е. я могу легко представить все эти объекты одним struct).

Поскольку в строке JSON есть несколько таких объектов, я считаю, что мне следует использовать serde_json::StreamDeserializer, хотя я относительно новичок в Rust и serde в частности, поэтому, если это не правильный подход, пожалуйста, укажите мне правильное направление.

Этот код представляет то, что я хочу сделать:

use serde_json::Deserializer;
use serde::Deserialize;

#[derive(Deserialize, Debug)]
struct Data {
    foo: String,
}

fn main() {
    let data = r#"{
        "a": {"foo": "bar"},
        "b": {"foo": "baz"}
    }"#;

    let stream = Deserializer::from_str(data).into_iter::<Data>();

    for value in stream {
        println!("{:?}", value.unwrap());
    }
}

Я ожидаю, что этот код выдаст что-то похожее на Object({"a": Object({"foo": String("bar")}), "b": Object({"foo": String("baz")})}).

Это результат, который я увижу, если изменю Deserializer::from_str(data).into_iter::<Data>(); на Deserializer::from_str(data).into_iter::<serde_json::Value>();.

Вместо этого код не компилируется, что приводит к ошибке Error("missing field 'foo'", line: 4, column: 5)

Итак, что мне нужно сделать, чтобы десериализовать JSON в структуры Data, а не Value?


person Charles German    schedule 31.10.2019    source источник
comment
то же самое, что и stackoverflow.com/q/44610594/7076153, вы можете сделать свой вопрос более общим, это будет отличный дубликат использовать для будущего вопроса   -  person Stargateur    schedule 31.10.2019


Ответы (1)


Оказывается, решение было намного проще, чем я думал. Спасибо /u/sfackler на Reddit за указание это для меня.

В этом сценарии мне не нужно использовать StreamDeserializer; вместо этого я могу просто разобрать JSON в HashMap и извлечь из него нужные мне значения.

Например:

use serde::Deserialize;
use std::collections::HashMap;

#[derive(Deserialize, Debug)]
struct Data {
    foo: String,
}

fn main() {
    let data = r#"{
        "a": {"foo": "bar"},
        "b": {"foo": "baz"}
    }"#;

    let m: HashMap<String, Data> = serde_json::from_str(&data).unwrap();
    for (_key, val) in m {
        println!("{:?}", val);
    }
}
person Charles German    schedule 31.10.2019