#serde #utilities #serialization #deserialization

serde_with

Custom de/serialization functions for Rust’s serde

24 releases (15 stable)

1.8.0 Mar 30, 2021
1.6.4 Feb 16, 2021
1.6.0 Nov 23, 2020
1.5.0-alpha.1 Jun 27, 2020
0.1.0 Aug 17, 2017

#3 in Encoding

Download history 12764/week @ 2020-12-23 15730/week @ 2020-12-30 22024/week @ 2021-01-06 21819/week @ 2021-01-13 25199/week @ 2021-01-20 24363/week @ 2021-01-27 23532/week @ 2021-02-03 26774/week @ 2021-02-10 27915/week @ 2021-02-17 27265/week @ 2021-02-24 29356/week @ 2021-03-03 30005/week @ 2021-03-10 30829/week @ 2021-03-17 37314/week @ 2021-03-24 36483/week @ 2021-03-31 30551/week @ 2021-04-07

112,703 downloads per month
Used in 170 crates (88 directly)

MIT/Apache

285KB
5K SLoC

Custom de/serialization functions for Rust's serde

docs.rs badge crates.io badge Build Status codecov


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:

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 this to your Cargo.toml:

[dependencies.serde_with]
version = "1.8.0"
features = [ "..." ]

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.

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

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.

#[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.

#[serde_as]
#[derive(Deserialize, Serialize)]
struct Foo {
     // Serialize them into a list of number as seconds
     #[serde_as(as = "Vec<DurationSeconds>")]
     durations: Vec<Duration>,
     // 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 = "BTreeMap<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)],
    bytes: vec![
        (1, vec![0, 1, 2]),
        (-100, vec![100, 200, 255]),
        (1, vec![0, 111, 222]),
    ],
}

// into this JSON
{
    "durations": [5, 3600, 0],
    "bytes": {
        "1": "000102",
        "-100": "64c8ff",
        "1": "006fde"
    }
}

License

Licensed under either of

at your option.

Contribution

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.

Dependencies

~0.5–1.2MB
~29K SLoC