如何仅序列化变体名称并忽略结构中枚举字段的值(serde)
How to serialise only name of variant and ignore value for enum field in struct (serde)
给定定义:
#[derive(Serialize, Deserialize)]
enum Bar {
A(i64),
B(u64),
}
#[derive(Serialize, Deserialize)]
struct Foo {
bar: Bar,
}
JSON 序列化
Foo {
bar: Bar::A(123),
}
将是:
{
"bar": "A"
}
理想的做法是向结构中的字段添加属性而不是在枚举定义中(枚举将在值也需要序列化的结构字段中重用)
属性 #[serde(skip)]
可用于元组变体字段:
use serde::{Serialize, Deserialize}; // 1.0.126
use serde_json; // 1.0.64
#[derive(Serialize, Deserialize)]
enum Bar {
A(#[serde(skip)] i64),
B(#[serde(skip)] u64),
}
#[derive(Serialize, Deserialize)]
struct Foo {
bar: Bar,
}
fn main() {
let foo = Foo { bar: Bar::A(123) };
println!("{}", serde_json::to_string(&foo).unwrap());
}
{"bar":"A"}
如果修改 Bar
不是一个选项,您将不得不通过 #[serde(with = ...)]
or #[serde(serialize_with = ...)]
:
进行更多的手动操作
use serde::{Serialize, Deserialize, ser::Serializer}; // 1.0.126
use serde_json; // 1.0.64
#[derive(Serialize, Deserialize)]
enum Bar {
A(i64),
B(u64),
}
#[derive(Serialize, Deserialize)]
struct Foo {
#[serde(serialize_with = "bar_name_only")]
bar: Bar,
}
fn bar_name_only<S>(bar: &Bar, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let name = match bar {
Bar::A(_) => "A",
Bar::B(_) => "B",
};
serializer.serialize_str(name)
}
fn main() {
let foo = Foo { bar: Bar::A(123) };
println!("{}", serde_json::to_string(&foo).unwrap());
}
{"bar":"A"}
给定定义:
#[derive(Serialize, Deserialize)]
enum Bar {
A(i64),
B(u64),
}
#[derive(Serialize, Deserialize)]
struct Foo {
bar: Bar,
}
JSON 序列化
Foo {
bar: Bar::A(123),
}
将是:
{
"bar": "A"
}
理想的做法是向结构中的字段添加属性而不是在枚举定义中(枚举将在值也需要序列化的结构字段中重用)
属性 #[serde(skip)]
可用于元组变体字段:
use serde::{Serialize, Deserialize}; // 1.0.126
use serde_json; // 1.0.64
#[derive(Serialize, Deserialize)]
enum Bar {
A(#[serde(skip)] i64),
B(#[serde(skip)] u64),
}
#[derive(Serialize, Deserialize)]
struct Foo {
bar: Bar,
}
fn main() {
let foo = Foo { bar: Bar::A(123) };
println!("{}", serde_json::to_string(&foo).unwrap());
}
{"bar":"A"}
如果修改 Bar
不是一个选项,您将不得不通过 #[serde(with = ...)]
or #[serde(serialize_with = ...)]
:
use serde::{Serialize, Deserialize, ser::Serializer}; // 1.0.126
use serde_json; // 1.0.64
#[derive(Serialize, Deserialize)]
enum Bar {
A(i64),
B(u64),
}
#[derive(Serialize, Deserialize)]
struct Foo {
#[serde(serialize_with = "bar_name_only")]
bar: Bar,
}
fn bar_name_only<S>(bar: &Bar, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let name = match bar {
Bar::A(_) => "A",
Bar::B(_) => "B",
};
serializer.serialize_str(name)
}
fn main() {
let foo = Foo { bar: Bar::A(123) };
println!("{}", serde_json::to_string(&foo).unwrap());
}
{"bar":"A"}