Trait serde_with::ser::SerializeAs
source · [−]pub trait SerializeAs<T: ?Sized> {
fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer;
}
Expand description
A data structure that can be serialized into any data format supported by Serde, analogue to Serialize
.
The trait is analogue to the serde::Serialize
trait, with the same meaning of input and output arguments.
It can and should the implemented using the same code structure as the Serialize
trait.
As such, the same advice for implementing Serialize
applies here.
Differences to Serialize
The trait is only required for container-like types or types implementing specific conversion functions.
Container-like types are Vec
, BTreeMap
, but also Option
and Box
.
Conversion types serialize into a different serde data type.
For example, DisplayFromStr
uses the Display
trait to serialize a String and DurationSeconds
converts a Duration
into either String or integer values.
This code shows how to implement Serialize
for Box
:
impl<T> Serialize for Box<T>
where
T: Serialize,
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
(**self).serialize(serializer)
}
}
and this code shows how to do the same using SerializeAs
:
impl<T, U> SerializeAs<Box<T>> for Box<U>
where
U: SerializeAs<T>,
{
fn serialize_as<S>(source: &Box<T>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
SerializeAsWrap::<T, U>::new(source).serialize(serializer)
}
}
It uses two type parameters, T
and U
instead of only one and performs the serialization step using the SerializeAsWrap
type.
The T
type is the on the Rust side before serialization, whereas the U
type determines how the value will be serialized.
These two changes are usually enough to make a container type implement SerializeAs
.
SerializeAsWrap
is a piece of glue code which turns SerializeAs
into a serde compatible datatype, by converting all calls to serialize
into serialize_as
.
This allows us to implement SerializeAs
such that it can be applied recursively throughout the whole data structure.
This is mostly important for container types, such as Vec
or BTreeMap
.
In a BTreeMap
this allows us to specify two different serialization behaviors, one for key and one for value, using the SerializeAs
trait.
Implementing a converter Type
This shows a simplified implementation for DisplayFromStr
.
struct DisplayFromStr;
impl<T> SerializeAs<T> for DisplayFromStr
where
T: Display,
{
fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.collect_str(&source)
}
}
Required Methods
fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error> where
S: Serializer,
fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error> where
S: Serializer,
Serialize this value into the given Serde serializer.