将 serde 用于两种(反)序列化格式
Using serde for two (de)serialization formats
我已经成功使用serde_json
反序列化和序列化JSON。我的设置看起来有点像这样(非常简单):
use serde::{Deserialize, Serialize};
use serde_json;
use serde_with::skip_serializing_none;
#[skip_serializing_none]
#[derive(Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
struct Foo {
#[serde(flatten)]
bar: Option<Bar>,
baz_quux: Option<u8>,
}
#[skip_serializing_none]
#[derive(Deserialize, Serialize)]
struct Bar {
#[serde(rename = "plughXyzzySomeRandomStuff")]
plugh_xyzzy: Option<u8>
}
然后我在 Foo
上实现了 FromStr
和 Display
,它们又分别调用 serde_json::from_str
和 serde_json::to_string
,很容易 (de)序列化结构。
但是,我现在还想使用 serde_ini
来支持将 INI 文件(反)序列化为相同的 Rust 数据结构。但我真的不知道该怎么做。
结构本身很简单,但我的具体问题在于属性:
- 按键在JSON和INI格式中的命名方式不同(JSON格式使用习惯的驼峰命名法,而INI没有),所以我必须解决
#[serde(rename)]
和 #[serde(rename_all)]
以其他方式表示属性,但我不确定在哪里或如何。
#[serde(flatten)]
doesn't seem to work 与 serde_ini
的全字符串值,这需要所有非字符串值的 #[serde(deserialize_with="from_str)]"
属性,但这显然只适用到 INI 值而不是 JSON 值。
所以总而言之,我想我需要做的是重新实现这些属性,或者根据使用的 (De)Serializer 有条件地使用它们,但我不知道该怎么做。
这是serde
设计的限制。 Deserialize
和 Serialize
实现与 Serializer
和 Deserializer
实现有意分开,这在选择不同格式和交换它们时提供了极大的灵活性和便利性。不幸的是,这意味着无法针对不同格式单独微调 Deserialize
和 Serialize
实现。
我之前这样做的方法是复制数据类型,以便我可以为每种格式配置它们,然后提供它们之间的零成本转换。
我已经成功使用serde_json
反序列化和序列化JSON。我的设置看起来有点像这样(非常简单):
use serde::{Deserialize, Serialize};
use serde_json;
use serde_with::skip_serializing_none;
#[skip_serializing_none]
#[derive(Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
struct Foo {
#[serde(flatten)]
bar: Option<Bar>,
baz_quux: Option<u8>,
}
#[skip_serializing_none]
#[derive(Deserialize, Serialize)]
struct Bar {
#[serde(rename = "plughXyzzySomeRandomStuff")]
plugh_xyzzy: Option<u8>
}
然后我在 Foo
上实现了 FromStr
和 Display
,它们又分别调用 serde_json::from_str
和 serde_json::to_string
,很容易 (de)序列化结构。
但是,我现在还想使用 serde_ini
来支持将 INI 文件(反)序列化为相同的 Rust 数据结构。但我真的不知道该怎么做。
结构本身很简单,但我的具体问题在于属性:
- 按键在JSON和INI格式中的命名方式不同(JSON格式使用习惯的驼峰命名法,而INI没有),所以我必须解决
#[serde(rename)]
和#[serde(rename_all)]
以其他方式表示属性,但我不确定在哪里或如何。 #[serde(flatten)]
doesn't seem to work 与serde_ini
的全字符串值,这需要所有非字符串值的#[serde(deserialize_with="from_str)]"
属性,但这显然只适用到 INI 值而不是 JSON 值。
所以总而言之,我想我需要做的是重新实现这些属性,或者根据使用的 (De)Serializer 有条件地使用它们,但我不知道该怎么做。
这是serde
设计的限制。 Deserialize
和 Serialize
实现与 Serializer
和 Deserializer
实现有意分开,这在选择不同格式和交换它们时提供了极大的灵活性和便利性。不幸的是,这意味着无法针对不同格式单独微调 Deserialize
和 Serialize
实现。
我之前这样做的方法是复制数据类型,以便我可以为每种格式配置它们,然后提供它们之间的零成本转换。