serde_with/de/mod.rs
1//! Module for [`DeserializeAs`][] implementations
2//!
3//! The module contains the [`DeserializeAs`][] trait and helper code.
4//! Additionally, it contains implementations of [`DeserializeAs`][] for types defined in the Rust Standard Library or this crate.
5//!
6//! You can find more details on how to implement this trait for your types in the documentation of the [`DeserializeAs`][] trait and details about the usage in the [user guide][].
7//!
8//! [user guide]: crate::guide
9
10#[cfg(feature = "alloc")]
11mod duplicates;
12mod impls;
13#[cfg(feature = "alloc")]
14mod skip_error;
15
16use crate::prelude::*;
17
18/// A **data structure** that can be deserialized from any data format supported by Serde, analogue to [`Deserialize`].
19///
20/// The trait is analogue to the [`serde::Deserialize`][`Deserialize`] trait, with the same meaning of input and output arguments.
21/// It can and should be implemented using the same code structure as the [`Deserialize`] trait.
22/// As such, the same advice for [implementing `Deserialize`][impl-deserialize] applies here.
23///
24/// # Differences to [`Deserialize`]
25///
26/// The trait is only required for container-like types or types implementing specific conversion functions.
27/// Container-like types are [`Vec`], [`BTreeMap`], but also [`Option`] and [`Box`].
28/// Conversion types deserialize into a different Rust type.
29/// For example, [`DisplayFromStr`] uses the [`FromStr`] trait after deserializing a string and [`DurationSeconds`] creates a [`Duration`] from either String or integer values.
30///
31/// This code shows how to implement [`Deserialize`] for [`Box`]:
32///
33/// ```rust,ignore
34/// impl<'de, T: Deserialize<'de>> Deserialize<'de> for Box<T> {
35/// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
36/// where
37/// D: Deserializer<'de>,
38/// {
39/// Ok(Box::new(Deserialize::deserialize(deserializer)?))
40/// }
41/// }
42/// ```
43///
44/// and this code shows how to do the same using [`DeserializeAs`][]:
45///
46/// ```rust,ignore
47/// impl<'de, T, U> DeserializeAs<'de, Box<T>> for Box<U>
48/// where
49/// U: DeserializeAs<'de, T>,
50/// {
51/// fn deserialize_as<D>(deserializer: D) -> Result<Box<T>, D::Error>
52/// where
53/// D: Deserializer<'de>,
54/// {
55/// Ok(Box::new(
56/// DeserializeAsWrap::<T, U>::deserialize(deserializer)?.into_inner(),
57/// ))
58/// }
59/// }
60/// ```
61///
62/// It uses two type parameters, `T` and `U` instead of only one and performs the deserialization step using the `DeserializeAsWrap` type.
63/// The `T` type is the type on the Rust side after deserialization, whereas the `U` type determines how the value will be deserialized.
64/// These two changes are usually enough to make a container type implement [`DeserializeAs`][].
65///
66///
67/// [`DeserializeAsWrap`] is a piece of glue code which turns [`DeserializeAs`] into a serde compatible datatype, by converting all calls to `deserialize` into `deserialize_as`.
68/// This allows us to implement [`DeserializeAs`] such that it can be applied recursively throughout the whole data structure.
69/// This is mostly important for container types, such as `Vec` or `BTreeMap`.
70/// In a `BTreeMap` this allows us to specify two different serialization behaviors, one for key and one for value, using the [`DeserializeAs`] trait.
71///
72/// ## Implementing a converter Type
73///
74/// This shows a simplified implementation for [`DisplayFromStr`].
75///
76/// ```rust
77/// # #[cfg(feature = "macros")] {
78/// # use serde::Deserialize;
79/// # use serde::de::Error;
80/// # use serde_with::{serde_as, DeserializeAs};
81/// # use std::str::FromStr;
82/// # use std::fmt::Display;
83/// struct DisplayFromStr;
84///
85/// impl<'de, T> DeserializeAs<'de, T> for DisplayFromStr
86/// where
87/// T: FromStr,
88/// T::Err: Display,
89/// {
90/// fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
91/// where
92/// D: serde::Deserializer<'de>,
93/// {
94/// let s = String::deserialize(deserializer).map_err(Error::custom)?;
95/// s.parse().map_err(Error::custom)
96/// }
97/// }
98/// #
99/// # #[serde_as]
100/// # #[derive(serde::Deserialize)]
101/// # struct S (#[serde_as(as = "DisplayFromStr")] bool);
102/// #
103/// # assert!(!serde_json::from_str::<S>(r#""false""#).unwrap().0);
104/// # }
105/// ```
106/// [`Box`]: std::boxed::Box
107/// [`BTreeMap`]: std::collections::BTreeMap
108/// [`Duration`]: std::time::Duration
109/// [`FromStr`]: std::str::FromStr
110/// [`Vec`]: std::vec::Vec
111/// [impl-deserialize]: https://serde.rs/impl-deserialize.html
112pub trait DeserializeAs<'de, T>: Sized {
113 /// Deserialize this value from the given Serde deserializer.
114 fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
115 where
116 D: Deserializer<'de>;
117}
118
119/// Helper type to implement [`DeserializeAs`] for container-like types.
120pub struct DeserializeAsWrap<T, U> {
121 value: T,
122 marker: PhantomData<U>,
123}
124
125impl<T, U> DeserializeAsWrap<T, U> {
126 /// Return the inner value of type `T`.
127 pub fn into_inner(self) -> T {
128 self.value
129 }
130}
131
132impl<'de, T, U> Deserialize<'de> for DeserializeAsWrap<T, U>
133where
134 U: DeserializeAs<'de, T>,
135{
136 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
137 where
138 D: Deserializer<'de>,
139 {
140 U::deserialize_as(deserializer).map(|value| Self {
141 value,
142 marker: PhantomData,
143 })
144 }
145}
146
147impl<T: ?Sized> As<T> {
148 /// Deserialize type `T` using [`DeserializeAs`][]
149 ///
150 /// The function signature is compatible with [serde's `with` annotation][with-annotation].
151 ///
152 /// [with-annotation]: https://serde.rs/field-attrs.html#with
153 pub fn deserialize<'de, D, I>(deserializer: D) -> Result<I, D::Error>
154 where
155 T: DeserializeAs<'de, I>,
156 D: Deserializer<'de>,
157 {
158 T::deserialize_as(deserializer)
159 }
160}