如何有条件地将JSON反序列化为枚举的两个不同变体?

如何有条件地将JSON反序列化为枚举的两个不同变体?,json,rust,serde,Json,Rust,Serde,假设我有如下JSON数据: { "type": "A", "value": [ 1, 2, 3, 4, 5 ] } 类型确定值的类型,在第一个示例中为Vec,在第二个示例中为Vec 如果我将上述数据表示为: 枚举数据值{ A型(Vec), B类(Vec) } 结构数据{ 数据类型:字符串, 值:数据值 } 如何实现serde反序列化以正确解码这些值?这可能是个人意见,但我通常会尝试避免对枚举进行序列化/反序列化 这不是C++中的同一件事吗?< /P> struct DataValue

假设我有如下JSON数据:

{
  "type": "A",
  "value": [ 1, 2, 3, 4, 5 ]
}
类型
确定
值的类型
,在第一个示例中为
Vec
,在第二个示例中为
Vec

如果我将上述数据表示为:

枚举数据值{
A型(Vec),
B类(Vec)
}
结构数据{
数据类型:字符串,
值:数据值
}

如何实现serde反序列化以正确解码这些值?

这可能是个人意见,但我通常会尝试避免对枚举进行序列化/反序列化

这不是C++中的同一件事吗?< /P>

struct DataValue final{
  TypeA(Vec<u32>) final,
  TypeB(Vec<Vec<u32>>) final
}

struct DataValue final{
A型(Vec)决赛,
B类(Vec)期末考试
}

幸运的是,
serde
内置了对以下各项的支持:

/#serde={version=“1.0.99”,功能=[“派生”]}
//#serde_json=“1.0.40”
使用serde::反序列化;
#[派生(反序列化、调试)]
#[serde(tag=“type”)]
枚举数据{
A{value:Vec},
B{value:Vec},
}
fn main(){
设a:Data=serde#u json::from_str(r#“{”type:“a”,“value:[1,2,3,4,5]}”).unwrap();
b:数据=
serde#u json::from#str(r#“{”type:“B”,“value:[[1,2,3,4,5],[6,7,8]}”).unwrap();
println!(“{:?}”,a);
println!(“{:?}”,b);
}

如果您向Serde提供足够的信息,让Serde知道如何执行此操作,您可以将JSON数据直接反序列化到
DataValue
的实例:

#[derive(Debug, Deserialize)]
#[serde(tag = "type", content = "value")]
enum DataValue {
    #[serde(rename = "A")]
    TypeA(Vec<u32>),
    #[serde(rename = "B")]
    TypeB(Vec<Vec<u32>>),
}

let data_a = r#"
    {
        "type": "A",
        "value": [1, 2, 3, 4, 5]
    }"#;
let a: DataValue = serde_json::from_str(data_a)?;

那是。。。甚至合法的C++?我不清楚除了“不要那样做”之外,你在说什么,这不是问题的答案。这既不符合问题的表达,也没有语义上的意义。即使假装它是有效的C++,也会说TypeA和TypeB数据都是有效的。这代表了软件中的一大类错误。请忘记这一点,不要让它永久化。好吧。。。像那个xd
#[derive(Debug, Deserialize)]
#[serde(tag = "type", content = "value")]
enum DataValue {
    #[serde(rename = "A")]
    TypeA(Vec<u32>),
    #[serde(rename = "B")]
    TypeB(Vec<Vec<u32>>),
}

let data_a = r#"
    {
        "type": "A",
        "value": [1, 2, 3, 4, 5]
    }"#;
let a: DataValue = serde_json::from_str(data_a)?;
impl DataValue {
    fn variant_name(&self) -> &'static str {
        match self {
            DataValue::TypeA(_) => "A",
            DataValue::TypeB(_) => "B",
        }
    }
}