50 个稳定版本
3.9.0 | 2024 年 7 月 14 日 |
---|---|
3.8.2 | 2024 年 6 月 30 日 |
3.7.0 | 2024 年 3 月 11 日 |
3.4.0 | 2023 年 10 月 17 日 |
0.1.0 | 2017 年 8 月 17 日 |
#2 in 编码
4,374,508 每月下载量
用于 4,236 个 crate(直接使用 1,092)
560KB
12K SLoC
为 Rust 的 serde 提供自定义的序列化和反序列化函数
此 crate 提供了自定义的序列化和反序列化辅助函数,可与 serde 的 with
注解 以及改进的 serde_as
注解一起使用。一些常见的用例包括:
- 使用
Display
和FromStr
特性序列化和反序列化类型,例如u8
、url::Url
或mime::Mime
。有关详细信息,请查看DisplayFromStr
。 - 支持超过 32 个元素的数组或使用 const 泛型。使用
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>
的文档。
获取帮助
查看用户指南,以获取有关此crate的更多技巧和窍门。
如需进一步的帮助使用此crate,您可以在GitHub上打开新的讨论或前往users.rust-lang.org提问。对于错误,请打开GitHub上的新问题。
在项目中使用 serde_with
# Add the current version to your Cargo.toml
cargo add serde_with
该crate包含与其它常用crate集成的不同功能。有关所有可用功能的详细信息,请参阅功能标志部分。
示例
注释您的结构体或枚举以启用自定义的反序列化和序列化。必须将#[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泛型。#[serde_as]
属性允许绕过这一限制,即使对于嵌套类型和嵌套数组也是如此。
此外,[u8; N]
(也称为字节)可以使用专门的"Bytes"
以提高效率,就像serde_bytes
crate一样。
#[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 的 with
注解 相比,serde_as
注解的灵活性。有关 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, Version 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.4–7MB
~43K SLoC