Module serde_with::guide::serde_as_transformations
source · [−]Expand description
De/Serialize Transformations Available
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 encode bytes
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",
Big Array support
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,...], ...],
bool
from integer
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,
Borrow from the input for Cow
type
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
with more efficiency
More efficient serialization for byte slices and similar.
// Rust
#[serde_as(as = "Bytes")]
value: Vec<u8>,
// JSON
"value": [0, 1, 2, 3, ...],
Convert to an intermediate type using Into
// 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],
Convert to an intermediate type using TryInto
// Rust
#[serde_as(as = "TryFromInto<i8>")]
value: u8,
// JSON
"value": 127,
Default
from null
// 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
De/Serialize into Vec
, ignoring errors
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]
De/Serialize with FromStr
and Display
Useful if a type implements FromStr
/ Display
but not Deserialize
/ Serialize
.
// Rust
#[serde_as(as = "serde_with::DisplayFromStr")]
value: u128,
#[serde_as(as = "serde_with::DisplayFromStr")]
mime: mime::Mime,
// JSON
"value": "340282366920938463463374607431768211455",
"mime": "text/*",
Duration
as seconds
// 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 encode bytes
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",
Ignore deserialization errors
Check the documentation for DefaultOnError
.
Maps
to Vec
of enums
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",
}
}
Maps
to Vec
of tuples
// 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.
NaiveDateTime
like UTC timestamp
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
None
as empty String
// Rust
#[serde_as(as = "serde_with::NoneAsEmptyString")]
value: Option<String>,
// JSON
"value": "", // converts to None
"value": "Hello World!", // converts to Some
One or many elements into Vec
// Rust
#[serde_as(as = "serde_with::OneOrMany<_>")]
value: Vec<String>,
// JSON
"value": "", // Deserializes single elements
"value": ["Hello", "World!"], // or lists of many
Pick first successful deserialization
// Rust
#[serde_as(as = "serde_with::PickFirst<(_, serde_with::DisplayFromStr)>")]
value: u32,
// JSON
// serialize into
"value": 666,
// deserialize from either
"value": 666,
"value": "666",
Timestamps as seconds since UNIX epoch
// 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 available for time::OffsetDateTime
and time::PrimitiveDateTime
with the time_0_3
feature enabled.
Value into JSON String
Some JSON APIs are weird and return a JSON encoded string in a JSON response
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}",
#[serde_as(as = "JsonString<Vec<(JsonString, _)>>")]
value: BTreeMap<[u8; 2], u32>,
// JSON
{"value":"[[\"[1,2]\",3],[\"[4,5]\",6]]"}
Vec
of tuples to Maps
// 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.
Well-known time formats for OffsetDateTime
time::OffsetDateTime
can be serialized in string format in different well-known formats.
Three formats are supported, time::format_description::well_known::Rfc2822
, time::format_description::well_known::Rfc3339
, and time::format_description::well_known::Iso8601
.
// 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,
#[serde_as(as = "time::format_description::well_known::Iso8601<Config>")]
iso_8601: OffsetDateTime,
// JSON
"rfc_2822": "Fri, 21 Nov 1997 09:55:06 -0600",
"rfc_3339": "1997-11-21T09:55:06-06:00",
"iso_8061": "1997-11-21T09:55:06-06:00",
These conversions are available with the time_0_3
feature flag.