This page 告诉您如何实现自定义映射反序列化器,这需要自定义visit_map 如何从输入数据中生成键值对。我基本上复制了该页面并制作了一个最小的示例来实现您正在寻找的内容。 Link to playground.
use std::fmt;
use std::marker::PhantomData;
use serde::de::{Deserialize, Deserializer, MapAccess, Visitor};
use serde_json::Value as JsonValue;
use std::collections::HashMap;
#[derive(Debug)]
struct MyMap(HashMap<String, JsonValue>);
impl MyMap {
fn with_capacity(capacity: usize) -> Self {
Self(HashMap::with_capacity(capacity))
}
}
struct MyMapVisitor {
marker: PhantomData<fn() -> MyMap>,
}
impl MyMapVisitor {
fn new() -> Self {
MyMapVisitor {
marker: PhantomData,
}
}
}
impl<'de> Visitor<'de> for MyMapVisitor {
// The type that our Visitor is going to produce.
type Value = MyMap;
// Format a message stating what data this Visitor expects to receive.
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a very special map")
}
// Deserialize MyMap from an abstract "map" provided by the
// Deserializer. The MapAccess input is a callback provided by
// the Deserializer to let us see each entry in the map.
fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
where
M: MapAccess<'de>,
{
let mut map = MyMap::with_capacity(access.size_hint().unwrap_or(0));
// While there are entries remaining in the input, add them
// into our map. Empty Objects get turned into Null.
while let Some((key, value)) = access.next_entry()? {
let value = match value {
JsonValue::Object(o) if o.is_empty() => JsonValue::Null,
_ => value,
};
map.0.insert(key, value);
}
Ok(map)
}
}
// This is the trait that informs Serde how to deserialize MyMap.
impl<'de> Deserialize<'de> for MyMap {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
// Instantiate our Visitor and ask the Deserializer to drive
// it over the input data, resulting in an instance of MyMap.
deserializer.deserialize_map(MyMapVisitor::new())
}
}
fn main() -> serde_json::Result<()> {
let json_str = r#"{"a": null, "b": {}, "c": {"valid_json": 42}}"#;
let v: MyMap = serde_json::from_str(json_str)?;
println!("{:?}", v);
Ok(())
}
这会打印出MyMap({"b": Null, "c": Object({"valid_json": Number(42)}), "a": Null}),我相信这就是您所追求的。