36 个稳定版本
3.9.0 | 2024年7月14日 |
---|---|
3.8.2 | 2024年6月30日 |
3.7.0 | 2024年3月11日 |
3.4.0 | 2023年10月17日 |
1.0.1 | 2019年4月8日 |
661 在 编码 中排名
4,244,490 每月下载量
被 1,129 个 crate (9 个直接使用) 使用
87KB
1K SLoC
Rust 的 serde 的自定义反序列化和序列化函数
该 crate 提供了自定义的反序列化和序列化助手,可以与 serde 的 with
注解 以及改进的 serde_as
注解结合使用。一些常见用例包括:
- 使用
Display
和FromStr
特性反序列化和序列化类型,例如u8
、url::Url
或mime::Mime
。有关详细信息,请查看DisplayFromStr
。 - 支持超过 32 个元素的数组或使用 const generics。使用
serde_as
,即使大型数组嵌套在其他类型中,也支持大型数组。以下示例展示了支持的情况:[bool; 64]
、Option<[u8; M]>
和Box<[[u8; 64]; N]>
。 - 使用
#[skip_serializing_none]
跳过所有空的Option
类型序列化。 - 使用
with_prefix!
为结构体的每个字段名添加前缀,而不改变结构体的反序列化/序列化实现。 - 将类似
#hash,#tags,#are,#great
的逗号分隔列表反序列化为Vec<String>
。请参阅serde_with::StringWithSeparator::<CommaSeparator, T>
的文档。
获取帮助
查看 用户指南 以获取更多关于此软件包的技巧和窍门。
若要进一步使用此软件包,您可以在 GitHub 上新建讨论 或在 users.rust-lang.org 上提问。对于错误,请在 GitHub 上新建 问题。
在项目中使用 serde_with
# Add the current version to your Cargo.toml
cargo add serde_with
该软件包包含不同功能,用于与其他常见软件包集成。请参阅 功能标志 部分,获取有关所有可用功能的信息。
示例
使用 #[serde_as]
属性注释您的结构体或枚举以启用自定义反序列化/序列化。此属性必须放在 #[derive]
之前。
as
与 serde 的 with
属性类似。您反映您想要反序列化/序列化的字段的类型结构。您可以指定字段的内部类型的转换器,例如,Vec<DisplayFromStr>
。您可以使用占位符 _
恢复默认的反序列化/序列化行为,例如,BTreeMap<_, DisplayFromStr>
。
DisplayFromStr
#[serde_as]
#[derive(Deserialize, Serialize)]
struct Foo {
// Serialize with Display, deserialize with FromStr
#[serde_as(as = "DisplayFromStr")]
bar: u8,
}
// This will serialize
Foo {bar: 12}
// into this JSON
{"bar": "12"}
大数组和 const 泛型数组
serde 不支持超过 32 个元素的数组或使用 const 泛型。[u8; N]
(也称为字节)可以使用专用 "Bytes"
进行高效处理,就像 serde_bytes
软件包一样。
除此之外,[u8; N]
(即字节)可以使用专门的 "Bytes"
以提高效率,就像 serde_bytes
软件包一样。
#[serde_as]
#[derive(Deserialize, Serialize)]
struct Arrays<const N: usize, const M: usize> {
#[serde_as(as = "[_; N]")]
constgeneric: [bool; N],
#[serde_as(as = "Box<[[_; 64]; N]>")]
nested: Box<[[u8; 64]; N]>,
#[serde_as(as = "Option<[_; M]>")]
optional: Option<[u8; M]>,
#[serde_as(as = "Bytes")]
bytes: [u8; M],
}
// This allows us to serialize a struct like this
let arrays: Arrays<100, 128> = Arrays {
constgeneric: [true; 100],
nested: Box::new([[111; 64]; 100]),
optional: Some([222; 128]),
bytes: [0x42; 128],
};
assert!(serde_json::to_string(&arrays).is_ok());
skip_serializing_none
这种情况在JSON中很常见,但其他格式也支持可选字段。如果有很多可选字段,将注释放在结构体上可能会变得繁琐。必须将属性 #[skip_serializing_none]
放置在 #[derive]
之前。
#[skip_serializing_none]
#[derive(Deserialize, Serialize)]
struct Foo {
a: Option<usize>,
b: Option<usize>,
c: Option<usize>,
d: Option<usize>,
e: Option<usize>,
f: Option<usize>,
g: Option<usize>,
}
// This will serialize
Foo {a: None, b: None, c: None, d: Some(4), e: None, f: None, g: Some(7)}
// into this JSON
{"d": 4, "g": 7}
高级 serde_as
使用
此示例主要旨在突出 serde_as
注解与 serde的 with
注解 相比时的灵活性。有关 serde_as
的更多详细信息,请参阅 用户指南。
use std::time::Duration;
#[serde_as]
#[derive(Deserialize, Serialize)]
enum Foo {
Durations(
// Serialize them into a list of number as seconds
#[serde_as(as = "Vec<DurationSeconds>")]
Vec<Duration>,
),
Bytes {
// We can treat a Vec like a map with duplicates.
// JSON only allows string keys, so convert i32 to strings
// The bytes will be hex encoded
#[serde_as(as = "Map<DisplayFromStr, Hex>")]
bytes: Vec<(i32, Vec<u8>)>,
}
}
// This will serialize
Foo::Durations(
vec![Duration::new(5, 0), Duration::new(3600, 0), Duration::new(0, 0)]
)
// into this JSON
{
"Durations": [5, 3600, 0]
}
// and serializes
Foo::Bytes {
bytes: vec![
(1, vec![0, 1, 2]),
(-100, vec![100, 200, 255]),
(1, vec![0, 111, 222]),
],
}
// into this JSON
{
"Bytes": {
"bytes": {
"1": "000102",
"-100": "64c8ff",
"1": "006fde"
}
}
}
许可协议
许可协议为以下之一
- Apache License,版本 2.0(LICENSE-APACHE 或 http://www.apache.org/licenses/LICENSE-2.0)
- MIT 许可协议(LICENSE-MIT 或 http://opensource.org/licenses/MIT)
任选其一。
贡献
有关详细的贡献说明,请阅读 CONTRIBUTING.md
。
除非你明确表示,否则根据 Apache-2.0 许可证定义,你故意提交以包含在你提交的工作中的任何贡献,都将如上所述双许可,没有额外的条款或条件。
依赖关系
~0.6–1MB
~24K SLoC