This page lists the transformations implemented in this crate and supported by serde_as
.
- Base64 encode bytes
- Big Array support
bool
from integer- Borrow from the input for
Cow
type Bytes
with more efficiency- Convert to an intermediate type using
Into
- Convert to an intermediate type using
TryInto
Default
fromnull
- De/Serialize into
Vec
, ignoring errors - De/Serialize with
FromStr
andDisplay
Duration
as seconds- Hex encode bytes
- Ignore deserialization errors
Maps
toVec
of enumsMaps
toVec
of tuplesNaiveDateTime
like UTC timestampNone
as emptyString
- One or many elements into
Vec
- Pick first successful deserialization
- Timestamps as seconds since UNIX epoch
- Value into JSON String
Vec
of tuples toMaps
- Well-known time formats for
OffsetDateTime
Base64
Requires the base64
feature.
The character set and padding behavior can be configured.
// Rust
#[serde_as(as = "serde_with::base64::Base64")]
value: Vec<u8>,
#[serde_as(as = "Base64<Bcrypt, Unpadded>")]
bcrypt_unpadded: Vec<u8>,
// JSON
"value": "SGVsbG8gV29ybGQ=",
"bcrypt_unpadded": "QETqZE6eT07wZEO",
Support for arrays of arbitrary size.
// Rust
#[serde_as(as = "[[_; 64]; 33]")]
value: [[u8; 64]; 33],
// JSON
"value": [[0,0,0,0,0,...], [0,0,0,...], ...],
Deserialize an integer and convert it into a bool
.
BoolFromInt<Strict>
(default) deserializes 0 to false
and 1
to true
, other numbers are errors.
BoolFromInt<Flexible>
deserializes any non-zero as true
.
Serialization only emits 0/1.
// Rust
#[serde_as(as = "BoolFromInt")] // BoolFromInt<Strict>
b: bool,
// JSON
"b": 1,
The types Cow<'_, str>
, Cow<'_, [u8]>
, or Cow<'_, [u8; N]>
can borrow from the input, avoiding extra copies.
// Rust
#[serde_as(as = "BorrowCow")]
value: Cow<'a, str>,
// JSON
"value": "foobar",
Bytes
More efficient serialization for byte slices and similar.
// Rust
#[serde_as(as = "Bytes")]
value: Vec<u8>,
// JSON
"value": [0, 1, 2, 3, ...],
FromInto
// Rust
#[serde_as(as = "FromInto<(u8, u8, u8)>")]
value: Rgb,
impl From<(u8, u8, u8)> for Rgb { ... }
impl From<Rgb> for (u8, u8, u8) { ... }
// JSON
"value": [128, 64, 32],
TryFromInto
// Rust
#[serde_as(as = "TryFromInto<i8>")]
value: u8,
// JSON
"value": 127,
DefaultOnNull
// Rust
#[serde_as(as = "DefaultOnNull")]
value: u32,
#[serde_as(as = "DefaultOnNull<DisplayFromStr>")]
value2: u32,
// JSON
"value": 123,
"value2": "999",
// Deserializes null into the Default value, i.e.,
null => 0
VecSkipError
For formats with heterogenous-typed sequences, we can collect only the deserializable elements. This is also useful for unknown enum variants.
#[derive(serde::Deserialize)]
enum Color {
Red,
Green,
Blue,
}
// JSON
"colors": ["Blue", "Yellow", "Green"],
// Rust
#[serde_as(as = "VecSkipError<_>")]
colors: Vec<Color>,
// => vec![Blue, Green]
Useful if a type implements FromStr
/ Display
but not Deserialize
/ Serialize
.
DisplayFromStr
// Rust
#[serde_as(as = "serde_with::DisplayFromStr")]
value: u128,
#[serde_as(as = "serde_with::DisplayFromStr")]
mime: mime::Mime,
// JSON
"value": "340282366920938463463374607431768211455",
"mime": "text/*",
DurationSeconds
// Rust
#[serde_as(as = "serde_with::DurationSeconds<u64>")]
value: Duration,
// JSON
"value": 86400,
DurationSecondsWithFrac
supports subsecond precision:
// Rust
#[serde_as(as = "serde_with::DurationSecondsWithFrac<f64>")]
value: Duration,
// JSON
"value": 1.234,
Different serialization formats are possible:
// Rust
#[serde_as(as = "serde_with::DurationSecondsWithFrac<String>")]
value: Duration,
// JSON
"value": "1.234",
The same conversions are also implemented for chrono::Duration
with the chrono
feature.
The same conversions are also implemented for time::Duration
with the time_0_3
feature.
Hex
Requires the hex
feature.
The hex string can use upper- and lowercase characters.
// Rust
#[serde_as(as = "serde_with::hex::Hex")]
lowercase: Vec<u8>,
#[serde_as(as = "serde_with::hex::Hex<serde_with::formats::Uppercase>")]
uppercase: Vec<u8>,
// JSON
"lowercase": "deadbeef",
"uppercase": "DEADBEEF",
Check the documentation for DefaultOnError
.
EnumMap
Combine multiple enum values into a single map. The key is the enum variant name, and the value is the variant value. This only works with externally tagged enums, the default enum representation. Other forms cannot be supported.
enum EnumValue {
Int(i32),
String(String),
Unit,
Tuple(i32, String),
Struct {
a: i32,
b: String,
},
}
// Rust
struct VecEnumValues (
#[serde_as(as = "EnumMap")]
Vec<EnumValue>,
);
VecEnumValues(vec![
EnumValue::Int(123),
EnumValue::String("Foo".to_string()),
EnumValue::Unit,
EnumValue::Tuple(1, "Bar".to_string()),
EnumValue::Struct {
a: 666,
b: "Baz".to_string(),
},
])
// JSON
{
"Int": 123,
"String": "Foo",
"Unit": null,
"Tuple": [
1,
"Bar",
],
"Struct": {
"a": 666,
"b": "Baz",
}
}
// Rust
#[serde_as(as = "Vec<(_, _)>")]
value: HashMap<String, u32>, // also works with BTreeMap
// JSON
"value": [
["hello", 1],
["world", 2]
],
The inverse operation is also available.
Requires the chrono
feature.
// Rust
#[serde_as(as = "chrono::DateTime<chrono::Utc>")]
value: chrono::NaiveDateTime,
// JSON
"value": "1994-11-05T08:15:30Z",
^ Pretend DateTime is UTC
NoneAsEmptyString
// Rust
#[serde_as(as = "serde_with::NoneAsEmptyString")]
value: Option<String>,
// JSON
"value": "", // converts to None
"value": "Hello World!", // converts to Some
OneOrMany
// Rust
#[serde_as(as = "serde_with::OneOrMany<_>")]
value: Vec<String>,
// JSON
"value": "", // Deserializes single elements
"value": ["Hello", "World!"], // or lists of many
PickFirst
// Rust
#[serde_as(as = "serde_with::PickFirst<(_, serde_with::DisplayFromStr)>")]
value: u32,
// JSON
// serialize into
"value": 666,
// deserialize from either
"value": 666,
"value": "666",
TimestampSeconds
// Rust
#[serde_as(as = "serde_with::TimestampSeconds<i64>")]
value: SystemTime,
// JSON
"value": 86400,
TimestampSecondsWithFrac
supports subsecond precision:
// Rust
#[serde_as(as = "serde_with::TimestampSecondsWithFrac<f64>")]
value: SystemTime,
// JSON
"value": 1.234,
Different serialization formats are possible:
// Rust
#[serde_as(as = "serde_with::TimestampSecondsWithFrac<String>")]
value: SystemTime,
// JSON
"value": "1.234",
The same conversions are also implemented for chrono::DateTime<Utc>
, chrono::DateTime<Local>
, and chrono::NaiveDateTime
with the chrono
feature.
The conversions are availble for time::OffsetDateTime
and time::PrimitiveDateTime
with the time_0_3
feature enabled.
Some JSON APIs are weird and return a JSON encoded string in a JSON response
JsonString
Requires the json
feature.
// Rust
#[derive(Deserialize, Serialize)]
struct OtherStruct {
value: usize,
}
#[serde_as(as = "serde_with::json::JsonString")]
value: OtherStruct,
// JSON
"value": "{\"value\":5}",
// Rust
#[serde_as(as = "HashMap<_, _>")] // also works with BTreeMap
value: Vec<(String, u32)>,
// JSON
"value": {
"hello": 1,
"world": 2
},
This operation is also available for other sequence types.
This includes BinaryHeap<(K, V)>
, BTreeSet<(K, V)>
, HashSet<(K, V)>
, LinkedList<(K, V)>
, VecDeque<(K, V)>
, Option<(K, V)>
and [(K, V); N]
for all sizes of N.
The inverse operation is also available.
time::OffsetDateTime
can be serialized in string format in different well-known formats.
Two formats are supported, time::format_description::well_known::Rfc2822
and time::format_description::well_known::Rfc3339
.
// Rust
#[serde_as(as = "time::format_description::well_known::Rfc2822")]
rfc_2822: OffsetDateTime,
#[serde_as(as = "time::format_description::well_known::Rfc3339")]
rfc_3339: OffsetDateTime,
// JSON
"rfc_2822": "Fri, 21 Nov 1997 09:55:06 -0600",
"rfc_3339": "1997-11-21T09:55:06-06:00",
These conversions are availble with the time_0_3
feature flag.