问题
I am writing a Rust application that handles JSON messages from a TypeScript client with a public interface. I have written some code using serde_derive
and it works well, but I can't figure out how to implement dictionaries; e.g.:
{
"foo" : { "data" : 42 },
"bar" : { "data" : 1337 }
}
Here the keys are the strings "foo"
and "bar"
and the dictionary's values follow this schema:
use serde_derive;
use serde_json::Number;
#[derive(Serialize, Deserialize)]
struct DictionaryValue {
data: Number,
}
I am looking to access the JSON data in this manner:
#[derive(Serialize, Deserialize)]
struct Dictionary {
key: String,
value: DictionaryValue,
}
How can I (de)serialize my JSON data into/from Dictionary
using Serde?
回答1:
You have a logic error in your code. The structure in your JSON file describes an associative array but your Dictionary
does not support multiple key-value-pairs. As Stargateur stated in the comments, you may use HashMap as Serde
has Serialize
and Deserialize
implementations for HashMap.
Instead of using a single key-value-pair, you can rewrite your Dictionary
as
type Dictionary = HashMap<String, DictionaryValue>;
and you can retrieve the data for example by
let dict: Dictionary = serde_json::from_str(json_string).unwrap();
If you now want to wrap everything in a Dictionary
-struct it will look like this:
#[derive(Serialize, Deserialize)]
struct Dictionary {
inner: HashMap<String, DictionaryValue>,
}
The problem is, that serde_json
now expects
{
"inner": {
"foo" : { "data" : 42 },
"bar" : { "data" : 1337 }
}
}
To get rid of this, you can add the serde(flatten)
attribute to Dictionary
:
#[derive(Serialize, Deserialize, Debug)]
struct Dictionary {
#[serde(flatten)]
inner: HashMap<String, DictionaryValue>,
}
If HashMap or any BTreeMap from std
does not fit your needs, you can also implement your Dictionary
on your own. See the docs here and here for more details.
来源:https://stackoverflow.com/questions/49717966/how-to-deserialize-a-strongly-typed-json-dictionary-in-serde