Apache License 2.0

项目介绍

jonasbb/serde_with 是一个托管在 GitHub 上的开源项目,主要使用 Rust 编写,采用 Apache License 2.0 许可证,目前获得 868 个 Star、98 次 Fork。

仓库全名
jonasbb/serde_with
开源许可证
Apache License 2.0
Star 数
868
Fork 数
98
未关闭 Issue
20

README 摘要

Custom de/serialization functions for Rust's serde This crate provides custom de/serialization helpers to use in combination with [serde's with annotation][with-annotation] and with the improved [serdeas][as-annotation]-annotation. Some common use cases are: De/Serializing a type using the Display and FromStr traits, e.g., for u8, url::Url, or mime::Mime. Check [DisplayFromStr] for details. Support for arrays larger…

完整内容见 GitHub 原始 README 或本页 。

常见问题

serde_with 用什么语言开发?

主要使用 Rust 编写,采用 Apache License 2.0 许可证,目前有 868 个 Star。

serde_with 可以免费商用吗?

仓库采用 Apache License 2.0 许可证,可免费使用与修改,商业使用请遵守许可证条款(例如保留版权声明与许可声明)。

如何获取 serde_with 的源码?

可以直接克隆仓库:git clone https://github.com/jonasbb/serde_with.git,默认分支为 master;安装与运行步骤见仓库 README。

serde_with 最近还在维护吗?

仓库最近一次更新为 1 周前,当前有 20 个未关闭 Issue;Star 数为 868,可作为社区活跃度的参考。

关于

GitHub 原始描述(英文)

This crate provides custom de/serialization helpers to use in combination with serde's `with`-annotation and with the improved `serde_as`-annotation.

描述取自 GitHub 官方 API,保持仓库作者书写的原文。

简要分析

热度分
1067
价值分
549
活跃状态
活跃

语言占比

Dockerfile
Rust

README

Custom de/serialization functions for Rust’s serde

crates.io badge Build Status codecov CII Best Practices


This crate provides custom de/serialization helpers to use in combination with serde’s with annotation and with the improved serde_as-annotation. Some common use cases are:

  • De/Serializing a type using the Display and FromStr traits, e.g., for u8, url::Url, or mime::Mime. Check DisplayFromStr for details.
  • Support for arrays larger than 32 elements or using const generics. With serde_as large arrays are supported, even if they are nested in other types. [bool; 64], Option<[u8; M]>, and Box<[[u8; 64]; N]> are all supported, as this examples shows.
  • Skip serializing all empty Option types with #[skip_serializing_none].
  • Apply a prefix / suffix to each field name of a struct, without changing the de/serialize implementations of the struct using with_prefix! / with_suffix!.
  • Deserialize a comma separated list like #hash,#tags,#are,#great into a Vec<String>. Check the documentation for serde_with::StringWithSeparator::<CommaSeparator, T>.

Getting Help

Check out the user guide to find out more tips and tricks about this crate.

For further help using this crate, you can open a new discussion or ask on users.rust-lang.org. For bugs, please open a new issue on GitHub.

Use serde_with in your Project

# Add the current version to your Cargo.toml
cargo add serde_with

The crate contains different features for integration with other common crates. Check the feature flags section for information about all available features.

Examples

Annotate your struct or enum to enable the custom de/serializer. The #[serde_as] attribute must be placed before the #[derive].

The as is analogous to the with attribute of serde. You mirror the type structure of the field you want to de/serialize. You can specify converters for the inner types of a field, e.g., Vec<DisplayFromStr>. The default de/serialization behavior can be restored by using _ as a placeholder, e.g., 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"}

Large and const-generic arrays

serde does not support arrays with more than 32 elements or using const-generics. The serde_as attribute allows circumventing this restriction, even for nested types and nested arrays.

On top of it, [u8; N] (aka, bytes) can use the specialized "Bytes" for efficiency much like the 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

This situation often occurs with JSON, but other formats also support optional fields. If many fields are optional, putting the annotations on the structs can become tedious. The #[skip_serializing_none] attribute must be placed before the #[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}

Advanced serde_as usage

This example is mainly supposed to highlight the flexibility of the serde_as annotation compared to serde’s with annotation. More details about serde_as can be found in the user guide.

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

License

Licensed under either of

at your option.

Contribution

For detailed contribution instructions please read CONTRIBUTING.md.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual-licensed as above, without any additional terms or conditions.

评论

暂无评论