Crate serde_with

Source
Expand description

crates.io badge Build Status codecov CII Best Practices Rustexplorer


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

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

§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.

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

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].

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}

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

Modules§

base64base64
De/Serialization of base64 encoded bytes
chronochrono
Legacy export of the chrono_0_4 module.
chrono_0_4chrono_0_4
De/Serialization of chrono types
de
Module for DeserializeAs implementations
formats
Specify the format and how lenient the deserialization is
guide
serde_with User Guide
hexhex
De/Serialization of hexadecimal encoded bytes
jsonjson
De/Serialization of JSON
rust
De/Serialization for Rust’s builtin and std types
schemars_0_8schemars_0_8
Integration with schemars v0.8.
ser
Module for SerializeAs implementations
time_0_3time_0_3
De/Serialization of time v0.3 types

Macros§

flattened_maybe
Support deserializing from flattened and non-flattened representation
serde_conv
Create new conversion adapters from functions
with_prefix
Serialize with an added prefix on every field name and deserialize by trimming away the prefix.
with_suffix
Serialize with an added suffix on every field name and deserialize by trimming away the suffix.

Structs§

As
Adapter to convert from serde_as to the serde traits.
BoolFromInt
Deserialize a boolean from a number
BorrowCow
Borrow Cow data during deserialization when possible.
Bytes
Optimized handling of owned and borrowed byte representations.
BytesOrString
Deserialize from bytes or string
DefaultOnError
Deserialize value and return Default on error
DefaultOnNull
Deserialize Default from null values
DisplayFromStr
De/Serialize using Display and FromStr implementation
DurationMicroSeconds
Equivalent to DurationSeconds with micro-seconds as base unit.
DurationMicroSecondsWithFrac
Equivalent to DurationSecondsWithFrac with micro-seconds as base unit.
DurationMilliSeconds
Equivalent to DurationSeconds with milli-seconds as base unit.
DurationMilliSecondsWithFrac
Equivalent to DurationSecondsWithFrac with milli-seconds as base unit.
DurationNanoSeconds
Equivalent to DurationSeconds with nano-seconds as base unit.
DurationNanoSecondsWithFrac
Equivalent to DurationSecondsWithFrac with nano-seconds as base unit.
DurationSeconds
De/Serialize Durations as number of seconds.
DurationSecondsWithFrac
De/Serialize Durations as number of seconds.
EnumMap
Represent a list of enum values as a map.
FromInto
Serialize value by converting to/from a proxy type with serde support.
FromIntoRef
Serialize a reference value by converting to/from a proxy type with serde support.
IfIsHumanReadable
Use the first format if De/Serializer::is_human_readable, otherwise use the second
KeyValueMap
Convert Vec elements into key-value map entries
Map
This serializes a list of tuples into a map
MapFirstKeyWins
Ensure that the first key is taken, if duplicate keys exist
MapPreventDuplicates
Ensure no duplicate keys exist in a map.
MapSkipError
Deserialize a map, skipping keys and values which fail to deserialize.
NoneAsEmptyString
De/Serialize a Option<String> type while transforming the empty string to None
OneOrMany
Deserialize one or many elements
PickFirst
Try multiple deserialization options until one succeeds.
Same
Adapter to convert from serde_as to the serde traits.
Schema
Helper for implementing JsonSchema on serializers whose output depends on the type of the concrete field.
Seq
De/Serialize a Map into a list of tuples
SetLastValueWins
Ensure that the last value is taken, if duplicate values exist
SetPreventDuplicates
Ensure no duplicate values exist in a set.
StringWithSeparator
De/Serialize a delimited collection using Display and FromStr implementation
TimestampMicroSeconds
Equivalent to TimestampSeconds with micro-seconds as base unit.
TimestampMicroSecondsWithFrac
Equivalent to TimestampSecondsWithFrac with micro-seconds as base unit.
TimestampMilliSeconds
Equivalent to TimestampSeconds with milli-seconds as base unit.
TimestampMilliSecondsWithFrac
Equivalent to TimestampSecondsWithFrac with milli-seconds as base unit.
TimestampNanoSeconds
Equivalent to TimestampSeconds with nano-seconds as base unit.
TimestampNanoSecondsWithFrac
Equivalent to TimestampSecondsWithFrac with nano-seconds as base unit.
TimestampSeconds
De/Serialize timestamps as seconds since the UNIX epoch
TimestampSecondsWithFrac
De/Serialize timestamps as seconds since the UNIX epoch
TryFromInto
Serialize value by converting to/from a proxy type with serde support.
TryFromIntoRef
Serialize a reference value by converting to/from a proxy type with serde support.
VecSkipError
Deserialize a sequence into Vec<T>, skipping elements which fail to deserialize.

Traits§

DeserializeAs
A data structure that can be deserialized from any data format supported by Serde, analogue to Deserialize.
SerializeAs
A data structure that can be serialized into any data format supported by Serde, analogue to Serialize.

Attribute Macros§

applymacros
Apply attributes to all fields with matching types
serde_asmacros
Convenience macro to use the serde_as system.
skip_serializing_nonemacros
Add skip_serializing_if annotations to [Option] fields.

Derive Macros§

DeserializeFromStrmacros
Deserialize value by using its FromStr implementation
SerializeDisplaymacros
Serialize value by using it’s Display implementation