【问题标题】:Support both serde_json::Value and cbor_json::Value同时支持 serde_json::Value 和 cbor_json::Value
【发布时间】:2020-10-02 10:00:36
【问题描述】:

如果我有一个布局未知的 JSON 值,我可以使用 serde_json 使用 serde_json::Value 反序列化它:

#[derive(Deserialize)]
struct Foo {
  unknown: serde_json::Value,
}

同样,我可以对 CBOR 做同样的事情:

#[derive(Deserialize)]
struct Foo {
  unknown: serde_cbor::Value,
}

但是,如果我想要一个可以从 JSON CBOR 加载的单一数据结构怎么办。我实际上想要这个:

enum UnknownValue {
  Json(serde_json::Value),
  Cbor(serde_cbor::Value),
}

#[derive(Deserialize)]
struct Foo {
  unknown: UnknownValue,
}

有什么方法可以将 JSON 或 CBOR 反序列化到这个结构中?

【问题讨论】:

  • 使用 untagged 肯定是有问题的地方
  • @Stargateur 我不知道这些是否适用,serde(untagged) 用于反序列化“正确的”锈级枚举,但他们想要的是从两个完全不同的反序列化通用无类型/非结构化值序列化库(json 和 cbor)。由于 cbor 数据类型看起来是 json 的超集,我建议将 serde_json::Value 转换为 serde_cbor::Value 并始终使用后者。或者,如果需要转换回来,您可能想做相反的事情(将有效的 cbor 输入限制为 json 兼容)。

标签: json rust serde cbor


【解决方案1】:

好的,我试过serde(untagged),它有点工作,除了它总是导致UnknownValue::Json,即使你使用serde_cbor反序列化。我不确定它是如何工作的:

use serde::Deserialize;

#[derive(Deserialize, Debug)]
#[serde(untagged)]
enum UnknownValue {
    Json(serde_json::Value),
    Cbor(serde_cbor::Value),
}

#[derive(Deserialize, Debug)]
struct Foo {
    unknown: UnknownValue,
}

fn main() {
    let json_input = br#"{"unknown": 23}"#;
    let cbor_input = [0xA1, 0x67, 0x75, 0x6E, 0x6B, 0x6E, 0x6F, 0x77, 0x6E, 0x17];

    let j: Foo = serde_json::from_slice(json_input).unwrap();
    let c: Foo = serde_cbor::from_slice(&cbor_input).unwrap();
    dbg!(j);
    dbg!(c);
}

打印

[src/main.rs:21] j = Foo {
    unknown: Number(
        23,
    ),
}
[src/main.rs:22] c = Foo {
    unknown: Number(
        23,
    ),
}

所以我想知道如果您使用serde_json::Value 并忘记枚举,它是否可以正常工作,瞧,它确实有效!使用它会得到完全相同的输出:

#[derive(Deserialize, Debug)]
struct Foo {
    unknown: serde_json::Value,
}

所以这并不能回答我的实际问题(例如,如果你想获得 CBOR 标签),但它确实满足了我的用例。可能还值得一提的是serde-value,它似乎是为这类事情设计的,虽然我还没有尝试过。

【讨论】:

  • 好吧,如果 masklinn 说 cbor 是 json 的超集,你必须把它放在第一位,serde untagged 接受第一个匹配项。
猜你喜欢
  • 1970-01-01
  • 2021-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-14
相关资源
最近更新 更多