问题描述
比方说我有如下的JSON数据:
{
"type": "A",
"value": [ 1, 2, 3, 4, 5 ]
}
{
"type": "B",
"value": [ [ 1, 2, 3, 4, 5 ], [ 6, 7, 8 ] ]
}
type
确定value
的类型,在第一个示例中为Vec<u32>
,在第二个示例中为Vec<Vec<u32>>
.
如果我将上述数据表示如下:
enum DataValue {
TypeA(Vec<u32>),
TypeB(Vec<Vec<u32>>)
}
struct Data {
data_type: String,
value: DataValue
}
如何实现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)?;
如果将枚举变量命名为A
和B
,则可以省略#[serde(rename = "…")]
属性.
这种枚举序列的方式称为相邻标记".您可以在有关枚举序列化的Serde文档中了解有关标记枚举的各种选项.. >
您的Data
结构包含一个冗余的附加标签data_type
.该信息已经在枚举中进行了编码,因此我认为您不需要此信息.如果您需要将此信息作为字符串,则可以将方法添加到枚举中:
impl DataValue {
fn variant_name(&self) -> &'static str {
match self {
DataValue::TypeA(_) => "A",
DataValue::TypeB(_) => "B",
}
}
}
Let's say I have JSON data like the following:
{
"type": "A",
"value": [ 1, 2, 3, 4, 5 ]
}
{
"type": "B",
"value": [ [ 1, 2, 3, 4, 5 ], [ 6, 7, 8 ] ]
}
type
determines the type of value
, which in the first example is Vec<u32>
and in the second is Vec<Vec<u32>>
.
If I represent the above data as follows:
enum DataValue {
TypeA(Vec<u32>),
TypeB(Vec<Vec<u32>>)
}
struct Data {
data_type: String,
value: DataValue
}
How do I implement serde deserialization to properly decode these values?
You can deserialize your JSON data directly to an instance of DataValue
if you give Serde enough information to know how to do this:
#[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)?;
If you name your enum variants A
and B
, you can omit the #[serde(rename = "…")]
attributes.
This way of serializing enums is called "adjacent tagging". You can learn about the various options of tagging enums in the Serde documentation on enum serialization.
Your Data
struct contains a redundant additional tag data_type
. This information is already encoded in the enum, so I don't think you need this. If you need this information as a string, you can add a method to the enum:
impl DataValue {
fn variant_name(&self) -> &'static str {
match self {
DataValue::TypeA(_) => "A",
DataValue::TypeB(_) => "B",
}
}
}
这篇关于如何有条件地将JSON反序列化为枚举的两个不同变体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!