我正在使用一个不太理想的 API,它不遵循任何严格的数据发送标准。每个有效负载在 JSON 之前都带有一些有效负载信息,然后是内部的实际数据,可以是单个字符串或多个字段。
就目前而言,如果我要将每个不同的有效负载映射到一个结构,我最终会得到大约 50 个结构。我觉得这并不理想,因为除了键之外,这些结构中有很多是重叠的。例如,我认为有 6 种不同版本的有效载荷可以映射到如下所示的内容,但它们都有不同的 key 。
我有这两个 JSON 示例:
{"key": "string"}
{"key2": "string"}
我想将两者序列化到这个结构中:
#[derive(Debug, Deserialize)]
struct SimpleString {
key: String,
}
对于两个字符串来说也是如此,甚至对于三个字符串也是如此。有效负载在一些小方面非常独特,所以我目前的解决方案是只在反序列化它们的函数内部定义本地结构,然后将数据传递到任何需要的地方(在我的例子中是缓存和事件处理程序)
有没有更好的方式来表示这个没有那么多重复?我试过寻找与 key 无关的反序列化之类的东西,但我还没有找到任何东西。
最佳答案
您可以为您的类型实现反序列化
来解码“ map ”并忽略键名:
extern crate serde;
extern crate serde_json;
use std::fmt;
use serde::de::{Deserialize, Deserializer, Error, MapAccess, Visitor};
fn main() {
let a = r#"{"key": "string"}"#;
let b = r#"{"key2": "string"}"#;
let a: SimpleString = serde_json::from_str(a).unwrap();
let b: SimpleString = serde_json::from_str(b).unwrap();
assert_eq!(a, b);
}
#[derive(Debug, PartialEq)]
struct SimpleString {
key: String,
}
struct SimpleStringVisitor;
impl<'de> Visitor<'de> for SimpleStringVisitor {
type Value = SimpleString;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("an object with a single string value of any key name")
}
fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
where
M: MapAccess<'de>,
{
if let Some((_, key)) = access.next_entry::<String, _>()? {
if access.next_entry::<String, String>()?.is_some() {
Err(M::Error::custom("too many values"))
} else {
Ok(SimpleString { key })
}
} else {
Err(M::Error::custom("not enough values"))
}
}
}
impl<'de> Deserialize<'de> for SimpleString {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_map(SimpleStringVisitor)
}
}
关于json - 如何对 JSON 对象进行 key 不可知的反序列化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47821224/