gpt4 book ai didi

rust - 有没有办法用 Serde 定义标签字段?

转载 作者:行者123 更新时间:2023-12-03 11:29:01 27 4
gpt4 key购买 nike

我想要这样的东西:

#[derive(Debug, Serialize, Deserialize)]
struct MyStruct {
field1: String,
field2: Option<u64>,
#[serde(tag(value = "tag_value"))]
tag: ()
}

#[serde(tag(value = "tag_value"))] 并不是 Serde 提供的实际属性,它只是表达一个想法。我知道我可以自己完成所有序列化,使用远程、(de)serialize_with 等,但这些需要大量样板代码。

思路是标签字段必须存在,序列化为JSON的MyStruct应该是:

{
"field1": "foo",
"field2": 42,
"tag": "tag_value"
}

如果“tag”字段缺失或映射到与“tag_value”不同的值,反序列化一定会失败。

最佳答案

使用单个变体枚举:

use serde; // 1.0.104
use serde_json; // 1.0.48

#[derive(Debug, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "snake_case")]
enum Tag {
TagValue,
}

#[derive(Debug, serde::Serialize, serde::Deserialize)]
struct MyStruct {
field1: String,
field2: Option<u64>,
tag: Tag,
}

fn main() {
let s = MyStruct {
field1: "foo".to_string(),
field2: Some(42),
tag: Tag::TagValue,
};

// The tag is included when serializing
println!("{:?}", serde_json::to_string(&s));

// Tag is required when deserializing
println!(
"{:?}",
serde_json::from_str::<MyStruct>(
"{\"field1\":\"foo\",\"field2\":42,\"tag\":\"tag_value\"}"
)
);
println!(
"{:?}",
serde_json::from_str::<MyStruct>("{\"field1\":\"foo\",\"field2\":42}")
);

// A bad tag fails
println!(
"{:?}",
serde_json::from_str::<MyStruct>("{\"field1\":\"foo\",\"field2\":42,\"tag\":\"oops\"}")
);
}

这打印

Ok("{\"field1\":\"foo\",\"field2\":42,\"tag\":\"tag_value\"}")
Ok(MyStruct { field1: "foo", field2: Some(42), tag: TagValue })
Err(Error("missing field `tag`", line: 1, column: 28))
Err(Error("unknown variant `oops`, expected `tag_value`", line: 1, column: 40))

( Permalink to the playground )

关于rust - 有没有办法用 Serde 定义标签字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61190379/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com