我正在使用一种不太理想的API,它不遵循任何严格的标准来发送数据。每个有效负载在JSON之前都附带一些有效负载信息,然后是实际数据,其中可以是单个字符串或多个字段。
现在看来,如果我将每个不同的有效负载映射到一个结构,我最终会得到大约50个结构。我觉得这并不理想,因为除了关键之外,大量的这些结构都是重叠的。例如,我相信有6种不同版本的有效载荷可以映射到类似下面的内容,但它们都有不同的密钥。
我有两个JSON示例:
{"key": "string"}
{"key2": "string"}
我想将两者都序列化为这个结构:
#[derive(Debug, Deserialize)]
struct SimpleString {
key: String,
}
对于两个字符串也可以这样说,甚至可以说三个字符串。有效载荷在很小的方面令人沮丧地独特,因此我目前的解决方案是在函数内部定义结构,对其进行反序列化,然后将数据传递到任何需要的位置(在我的情况下是缓存和事件处理程序)
有没有更好的方法来表示没有这么多重复?我已经尝试过寻找关键无关反序列化的东西,但我还没有找到任何东西。
答案 0 :(得分:1)
您可以为您的类型实施Deserialize
来解码"地图"并忽略密钥名称:
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)
}
}