Reputation: 1085
I want to parse a JSON string of the form
{
"a": {
"foo": "bar"
},
"b": {
"foo": "baz"
}
}
That is, at the top level there are a number of JSON objects separated by commas.
Each of these objects have the same fields as the others (i.e., I can easily represent all of these objects with a single struct
).
Since there are several of these objects in the JSON string, I believe I should be using a serde_json::StreamDeserializer
, though I am relatively new to Rust and serde
in particular, so if this is not the right approach, please point me in the correct direction.
This code represents what I want to do:
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());
}
}
I would expect this code to produce some output similar to Object({"a": Object({"foo": String("bar")}), "b": Object({"foo": String("baz")})})
.
This is the output I see if I change Deserializer::from_str(data).into_iter::<Data>();
to Deserializer::from_str(data).into_iter::<serde_json::Value>();
.
Instead, the code fails to compile, giving the error Error("missing field 'foo'", line: 4, column: 5)
So, what do I need to do in order to deserialize the JSON into Data
structs rather than Value
?
Upvotes: 1
Views: 806
Reputation: 1085
Turns out the solution was much simpler than I thought. Credit to /u/sfackler on Reddit for pointing this out to me.
In this scenario, I don't need to use a StreamDeserializer
; instead, I can just parse the JSON into a HashMap
and extract the values I want from it.
For example:
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);
}
}
Upvotes: 1