If I have a JSON value with unknown layout I can deserialise it with serde_json
using serde_json::Value
:
#[derive(Deserialize)]
struct Foo {
unknown: serde_json::Value,
}
Similarly I can do the same with CBOR:
#[derive(Deserialize)]
struct Foo {
unknown: serde_cbor::Value,
}
But what if I want a single data structure that can be loaded from JSON or CBOR. I effectively want this:
enum UnknownValue {
Json(serde_json::Value),
Cbor(serde_cbor::Value),
}
#[derive(Deserialize)]
struct Foo {
unknown: UnknownValue,
}
Is there any way to do this so that I can deserialise JSON or CBOR into this struct?
Ok, I tried serde(untagged)
, and it sort of works, except that it always results in UnknownValue::Json
, even if you deserialise using serde_cbor. I'm not sure how that works exactly:
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);
}
Prints
[src/main.rs:21] j = Foo {
unknown: Number(
23,
),
}
[src/main.rs:22] c = Foo {
unknown: Number(
23,
),
}
So I wondered if maybe it just works if you use serde_json::Value
and forget the enum, and lo, it does! Using this instead gives exactly the same output:
#[derive(Deserialize, Debug)]
struct Foo {
unknown: serde_json::Value,
}
So this doesn't answer my actual question (eg if you want to get CBOR tags), but it does satisfy my use case. Probably also worth mentioning serde-value which seems designed for this sort of thing, though I haven't tried it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.