json - 如何对 JSON 对象进行 key 不可知的反序列化?

标签 json rust serde

我正在使用一个不太理想的 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/

相关文章:

javascript - Node.js - 将平面 json 转换为不带 'parent' ,'child' 属性的分层 json

rust - 找不到将 char 转换为 u8 的方法

rust - 反序列化具有通用类型的可选结构字段会导致语义怪异

rust - 如何使用 serde 重命名 `start` 和 `end` 范围值?

rust - 我得到的特征绑定(bind) `T: sns_pub::_IMPL_DESERIALIZE_FOR_Message::_serde::Serialize` 不满意

javascript - 如何在 html Angular 中显示嵌套的 json 元素

json - Postgresql - 使用一个表中的选定列作为 json select 语句

javascript - AngularJS 用户登录到 Json 文件

import - 无法导入 StrBuf?

compiler-errors - 如何使用 Ord::max 函数?