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编码 中排名

Download history 747951/week @ 2024-04-28 792172/week @ 2024-05-05 843778/week @ 2024-05-12 839753/week @ 2024-05-19 876116/week @ 2024-05-26 976312/week @ 2024-06-02 963878/week @ 2024-06-09 923221/week @ 2024-06-16 957842/week @ 2024-06-23 883270/week @ 2024-06-30 985113/week @ 2024-07-07 966671/week @ 2024-07-14 1019907/week @ 2024-07-21 1063826/week @ 2024-07-28 1038600/week @ 2024-08-04 1083594/week @ 2024-08-11

4,244,490 每月下载量
1,129 个 crate (9 个直接使用) 使用

MIT/Apache 协议

87KB
1K 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 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

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 泛型。[u8; N](也称为字节)可以使用专用 "Bytes" 进行高效处理,就像 serde_bytes 软件包一样。

除此之外,[u8; N](即字节)可以使用专门的 "Bytes" 以提高效率,就像 serde_bytes 软件包一样。

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_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"
        }
    }
}

许可协议

许可协议为以下之一

任选其一。

贡献

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

除非你明确表示,否则根据 Apache-2.0 许可证定义,你故意提交以包含在你提交的工作中的任何贡献,都将如上所述双许可,没有额外的条款或条件。

依赖关系

~0.6–1MB
~24K SLoC