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:
Display
and FromStr
traits, e.g., for u8
, url::Url
, or mime::Mime
.
Check DisplayFromStr
or serde_with::rust::display_fromstr
for details.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.Option
types with #[skip_serializing_none]
.with_prefix!
.#hash,#tags,#are,#great
into a Vec<String>
.
Check the documentation for serde_with::rust::StringWithSeparator::<CommaSeparator>
.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.
serde_with
in your ProjectAdd this to your Cargo.toml
:
[dependencies.serde_with]
version = "1.11.0"
features = [ "..." ]
The crate contains different features for integration with other common crates. Check the feature flags section for information about all available features.
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"}
serde does not support arrays with more than 32 elements or using const-generics.
The serde_as
attribute allows to circumvent this restriction, even for nested types and nested arrays.
#[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]>,
}
// 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])
};
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.
#[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
usageThis 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"
}
}
Module for DeserializeAs
implementations
Specify the format and how lenient the deserialization is
De/Serialization for Rust’s builtin and std types
Module for SerializeAs
implementations
Support deserializing from flattened and non-flattened representation
Create new conversion adapters from functions
Serialize with an added prefix on every field name and deserialize by trimming away the prefix.
Adapter to convert from serde_as
to the serde traits.
Borrow Cow
data during deserialization when possible.
Optimized handling of owned and borrowed byte representations.
Deserialize from bytes or string
Predefined separator using a single comma
Deserialize value and return Default
on error
Deserialize Default
from null
values
Equivalent to DurationSeconds
with micro-seconds as base unit.
Equivalent to DurationSecondsWithFrac
with micro-seconds as base unit.
Equivalent to DurationSeconds
with milli-seconds as base unit.
Equivalent to DurationSecondsWithFrac
with milli-seconds as base unit.
Equivalent to DurationSeconds
with nano-seconds as base unit.
Equivalent to DurationSecondsWithFrac
with nano-seconds as base unit.
De/Serialize Durations as number of seconds.
De/Serialize Durations as number of seconds.
Serialize value by converting to/from a proxy type with serde support.
De/Serialize a Option<String>
type while transforming the empty string to None
Deserialize one or many elements
Try multiple deserialization options until one succeeds.
Adapter to convert from serde_as
to the serde traits.
Predefined separator using a single space
Equivalent to TimestampSeconds
with micro-seconds as base unit.
Equivalent to TimestampSecondsWithFrac
with micro-seconds as base unit.
Equivalent to TimestampSeconds
with milli-seconds as base unit.
Equivalent to TimestampSecondsWithFrac
with milli-seconds as base unit.
Equivalent to TimestampSeconds
with nano-seconds as base unit.
Equivalent to TimestampSecondsWithFrac
with nano-seconds as base unit.
De/Serialize timestamps as seconds since the UNIX epoch
De/Serialize timestamps as seconds since the UNIX epoch
Serialize value by converting to/from a proxy type with serde support.
A data structure that can be deserialized from any data format supported by Serde, analogue to Deserialize
.
Separator for string-based collection de/serialization
A data structure that can be serialized into any data format supported by Serde, analogue to Serialize
.
Add skip_serializing_if
annotations to Option
fields.