#serde-json #deserialize #derive-deserialize #serialization #serde

no-std serde_with

为 Rust 的 serde 提供自定义的序列化和反序列化函数

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 编码

Download history 801406/week @ 2024-05-03 848003/week @ 2024-05-10 844139/week @ 2024-05-17 882538/week @ 2024-05-24 988971/week @ 2024-05-31 988569/week @ 2024-06-07 948084/week @ 2024-06-14 983938/week @ 2024-06-21 934498/week @ 2024-06-28 971673/week @ 2024-07-05 992231/week @ 2024-07-12 1020917/week @ 2024-07-19 1047360/week @ 2024-07-26 1076238/week @ 2024-08-02 1140002/week @ 2024-08-09 914532/week @ 2024-08-16

4,374,508 每月下载量
用于 4,236 个 crate(直接使用 1,092

MIT/Apache 许可证

560KB
12K SLoC

为 Rust 的 serde 提供自定义的序列化和反序列化函数

crates.io badge Build Status codecov CII Best Practices Rustexplorer


此 crate 提供了自定义的序列化和反序列化辅助函数,可与 serde 的 with 注解 以及改进的 serde_as 注解一起使用。一些常见的用例包括:

  • 使用 DisplayFromStr 特性序列化和反序列化类型,例如 u8url::Urlmime::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

Rustexplorer

#[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一样。

Rustexplorer

#[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]之前。

Rustexplorer

#[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"
        }
    }
}

许可证

根据以下任一许可证授权:

由您选择。

贡献

有关详细的贡献说明,请阅读 CONTRIBUTING.md

除非您明确声明,否则根据 Apache-2.0 许可证定义的,您有意提交以包含在作品中的任何贡献,都将如上所述双许可,不附加任何其他条款或条件。

依赖项

~0.4–7MB
~43K SLoC