Skip to main content

deser_core/adapters/
mod.rs

1//! Adapters to customize how values are serialized and deserialized.
2//!
3//! An adapter is a type that knows how to serialize or deserialize a value of
4//! *another* type.  [`Serialize`] and [`Deserialize`] have a type parameter
5//! for the type of the value which defaults to `Self`: adapters implement
6//! `Serialize<T>` and `Deserialize<'de, T>` for the types `T` they support.
7//! They are typically zero sized marker types which are never instantiated.
8//!
9//! Adapters compose: the standard containers are adapters for the same
10//! container holding other types.  For instance `Vec<U>` is an adapter for
11//! `Vec<T>` if `U` is an adapter for `T` and `Option<U>` is an adapter for
12//! `Option<T>`.  A type is an adapter for itself, `Vec<T>` serializes with
13//! `Vec<T>` as adapter for `Vec<T>`.  [`Same`] is the adapter that uses the
14//! implementations of the type itself (which is useful where the type
15//! cannot be named, like in the derive).
16//!
17//! With the derive, adapters are selected with `#[deser(as = ...)]`.  In the
18//! attribute `_` can be used as a shorthand for [`Same`]:
19//!
20//! ```
21//! use std::collections::BTreeMap;
22//! use std::net::IpAddr;
23//! use deser::{Deserialize, Serialize};
24//! use deser::adapters::DisplayFromStr;
25//!
26//! #[derive(Serialize, Deserialize)]
27//! pub struct Config {
28//!     #[deser(as = DisplayFromStr)]
29//!     listen: IpAddr,
30//!     #[deser(as = Option<DisplayFromStr>)]
31//!     upstream: Option<IpAddr>,
32//!     #[deser(as = BTreeMap<_, Vec<DisplayFromStr>>)]
33//!     aliases: BTreeMap<String, Vec<IpAddr>>,
34//! }
35//! ```
36//!
37//! Missing fields are handled by the adapter (see
38//! [`Deserialize::initial_value`]) so in the example above `upstream` is
39//! optional as `Option<U>` makes missing values `None`.
40//!
41//! `serialize_as` and `deserialize_as` select an adapter for one direction
42//! only.  All three attributes can also be placed on structs, enums and
43//! unions to serialize and deserialize the type itself with an adapter (see
44//! [container adapters][container-adapters]).
45//!
46//! To use an adapter outside of the derive, the [`As`] wrapper can be used.
47//! It holds a value and serializes and deserializes it with an adapter.
48//!
49//! # Provided Adapters
50//!
51//! * [`Same`]: uses [`Serialize`] and [`Deserialize`] of the type itself.
52//! * [`DisplayFromStr`]: serializes with [`Display`](core::fmt::Display) and
53//!   deserializes with [`FromStr`](core::str::FromStr).
54//! * [`FromInto`] and [`TryFromInto`]: convert from and into another type.
55//! * [`DefaultOnError`]: uses the [`Default`] if a value cannot be
56//!   deserialized.
57//! * [`VecSkipError`] and [`MapSkipError`]: skip elements and entries that
58//!   cannot be deserialized.
59//! * [`Borrowed`]: deserializes a `Cow<str>` or `Cow<[u8]>` borrowed from the
60//!   data if possible.
61//! * [`Flag`]: a `bool` which is set by giving its key (like `?recursive`
62//!   in a query string).
63//! * [`Separated`]: a sequence written as text with a separator (like
64//!   `a,b,c` in an environment variable).
65//! * [`TrimWhitespace`]: trims whitespace from strings before they are
66//!   deserialized.
67//! * [`SkipBlank`]: leaves no value for blank strings, which leaves them
68//!   out of sequences.
69//! * The adapters for bytes: the base64 encodings (for instance
70//!   [`Base64Url`]) and [`BytesFallback`] (see [bytes](#bytes)).
71//! * The standard containers: `Option<U>`, `Result<U, V>`, `Box<U>`,
72//!   `Arc<U>`, `Vec<U>`, `VecDeque<U>`, `LinkedList<U>`, `BinaryHeap<U>`,
73//!   `[U]`, `[U; N]`, `Box<[U]>`, `Arc<[U]>`, `BTreeMap<K, V>`,
74//!   `HashMap<K, V>`, `BTreeSet<U>`, `HashSet<U>` and tuples.  With the
75//!   features of the same names also the collections of `indexmap`,
76//!   `hashbrown`, `smallvec` and `arrayvec` (for instance `IndexMap<K, V>`
77//!   and `SmallVec<[U; N]>`).
78//!
79//! # Bytes
80//!
81//! Bytes (`Vec<u8>`, `[u8; N]`, `&[u8]` and `Cow<[u8]>`) are part of the
82//! data model as [`Atom::Bytes`].  Formats which support
83//! bytes natively (such as CBOR) use that, text formats like JSON and TOML
84//! have to represent them differently.  In deser the convention is:
85//!
86//! * Formats without native bytes write bytes as base64 strings (RFC 4648,
87//!   standard alphabet with padding).  A different
88//!   [`BytesFormat`](crate::BytesFormat) can be configured in the
89//!   [`Context`](crate::Context) (for instance to write sequences of
90//!   integers).
91//! * Types that expect bytes accept a string and decode it.  By default
92//!   this is lenient base64: both the standard and the URL-safe alphabet
93//!   are accepted and the padding is optional.  Sequences of integers are
94//!   always accepted.
95//!
96//! ## Adapters
97//!
98//! How the bytes of an individual value are represented can be changed with
99//! these adapters.  They support `Vec<u8>`, `[u8; N]` and
100//! `Cow<[u8]>` (see [`BytesBuf`]).
101//!
102//! * The encodings (such as [`Base64Url`]) are adapters which represent
103//!   bytes as strings in the encoding in all formats, also in formats with
104//!   native bytes.
105//! * [`BytesFallback`] keeps bytes as bytes in formats with native bytes and
106//!   only picks the representation for formats without them.  This can be
107//!   an encoding (`BytesFallback<Base64Url>`) or sequences of integers
108//!   (`BytesFallback<IntSeq>`).
109//!
110//! ```
111//! use deser::adapters::{Base64Url, Base64UrlNoPad, BytesFallback, IntSeq};
112//! use deser::{Deserialize, Serialize};
113//!
114//! #[derive(Serialize, Deserialize)]
115//! pub struct Blob {
116//!     // base64 in JSON and TOML, bytes in CBOR
117//!     data: Vec<u8>,
118//!     // a URL-safe base64 string in all formats
119//!     #[deser(as = Base64UrlNoPad)]
120//!     token: [u8; 32],
121//!     // URL-safe base64 in JSON and TOML, bytes in CBOR
122//!     #[deser(as = BytesFallback<Base64Url>)]
123//!     signature: Vec<u8>,
124//!     // `[1, 2]` in JSON and TOML, bytes in CBOR
125//!     #[deser(as = BytesFallback<IntSeq>)]
126//!     legacy: Vec<u8>,
127//! }
128//! ```
129//!
130//! When deserializing, all of these accept native bytes and strings in
131//! their encoding.
132//!
133//! ## Encodings
134//!
135//! deser provides the base64 encodings:
136//!
137//! | Encoding           | Description                                        |
138//! |--------------------|----------------------------------------------------|
139//! | [`Base64`]         | base64, standard alphabet with padding             |
140//! | [`Base64NoPad`]    | base64, standard alphabet without padding          |
141//! | [`Base64Url`]      | base64, URL-safe alphabet with padding             |
142//! | [`Base64UrlNoPad`] | base64, URL-safe alphabet without padding          |
143//!
144//! They all decode leniently like the default: both alphabets are accepted
145//! and the padding is optional.
146//!
147//! More encodings (hexadecimal and base32) are provided by
148//! [`deser-encoding`](https://docs.rs/deser-encoding).  Other encodings can
149//! be added by implementing [`BytesEncoding`].  They are adapters like the
150//! encodings provided by deser.
151//!
152//! # Implementing Adapters
153//!
154//! Adapters implement [`Deserialize`] and [`Serialize`] for a type that is
155//! not `Self`.  This example serializes a byte vector into a hex string
156//! (`deser-encoding` provides this as `Hex`, and for bytes implementing
157//! [`BytesEncoding`] is less work):
158//!
159//! ```
160//! use std::borrow::Cow;
161//! use deser::de::{Slot, default_atom};
162//! use deser::ser::Emit;
163//! use deser::{Atom, Deserialize, Error, ErrorKind, Serialize, State};
164//!
165//! pub struct Hex;
166//!
167//! impl Serialize<Vec<u8>> for Hex {
168//!     fn serialize<'a>(
169//!         value: &'a Vec<u8>,
170//!         _state: &mut State,
171//!     ) -> Result<Emit<'a>, Error> {
172//!         let hex: String =
173//!             value.iter().map(|x| format!("{:02x}", x)).collect();
174//!         Ok(Emit::Atom(Atom::Str(hex.into())))
175//!     }
176//! }
177//!
178//! impl<'de> Deserialize<'de, Vec<u8>> for Hex {
179//!     fn deserialize_atom(
180//!         slot: &mut Slot<Vec<u8>, Self>,
181//!         atom: Atom,
182//!         state: &mut State,
183//!     ) -> Result<(), Error> {
184//!         match atom {
185//!             Atom::Str(ref s) if s.len() % 2 == 0 => {
186//!                 let bytes = (0..s.len())
187//!                     .step_by(2)
188//!                     .map(|i| u8::from_str_radix(&s[i..i + 2], 16))
189//!                     .collect::<Result<Vec<_>, _>>()
190//!                     .map_err(|_| {
191//!                         Error::new(ErrorKind::InvalidValue, "invalid hex")
192//!                     })?;
193//!                 slot.set(bytes);
194//!                 Ok(())
195//!             }
196//!             other => default_atom(slot, other, state),
197//!         }
198//!     }
199//!
200//!     fn expecting() -> Cow<'static, str> {
201//!         Cow::Borrowed("hex string")
202//!     }
203//! }
204//!
205//! #[derive(deser::Serialize, deser::Deserialize)]
206//! pub struct Blob {
207//!     #[deser(as = Hex)]
208//!     data: Vec<u8>,
209//!     #[deser(as = Vec<Hex>)]
210//!     parts: Vec<Vec<u8>>,
211//! }
212//! ```
213//!
214//! Implementations generic over adapters (like wrappers of other adapters)
215//! need the adapters to outlive the sinks and emitters that use them.  If
216//! they are not generic over the lifetime of these (like `Vec<A>` for
217//! `Vec<T>`), they require the adapters to be `'static`, which is the case
218//! for marker types.
219//!
220#![cfg_attr(
221    feature = "derive",
222    doc = "[container-adapters]: crate::derive#container-adapters"
223)]
224#![cfg_attr(
225    not(feature = "derive"),
226    doc = "[container-adapters]: https://docs.rs/deser/latest/deser/derive/index.html#container-adapters"
227)]
228
229use alloc::borrow::Cow;
230use alloc::vec::Vec;
231use core::cmp::Ordering;
232use core::fmt;
233use core::hash::{Hash, Hasher};
234use core::marker::PhantomData;
235use core::ops::{Deref, DerefMut};
236
237use crate::State;
238use crate::de::{Deserialize, InlineSeq, OwnedSink, SinkHandle};
239use crate::error::Error;
240use crate::event::{Atom, ContainerShape};
241use crate::ser::{Begin, Describe, Emit, PlainSink, Serialize};
242
243pub(crate) mod bytes;
244mod derived;
245mod stock;
246mod text;
247
248pub use self::bytes::{
249    Base64, Base64NoPad, Base64Url, Base64UrlNoPad, BytesBuf, BytesEncoding, BytesFallback,
250    BytesFallbackFormat, IntSeq,
251};
252pub use self::derived::Derived;
253#[doc(hidden)]
254pub use self::derived::{DerivedDeserialize, DerivedSerialize};
255pub use self::stock::{
256    Borrowed, DefaultOnError, DisplayFromStr, Flag, FromInto, MapSkipError, TryFromInto,
257    VecSkipError,
258};
259pub use self::text::{Separated, SkipBlank, TrimWhitespace};
260// used for the maps of other crates
261#[allow(unused_imports)]
262pub(crate) use self::stock::skip_map_sink;
263
264/// The adapter that uses the type's own implementation.
265///
266/// This forwards to [`Serialize`] and [`Deserialize`].  In
267/// `#[deser(as = ...)]` attributes `_` can be used instead.
268///
269/// ```
270/// use std::collections::BTreeMap;
271/// use deser::Deserialize;
272/// use deser::adapters::DisplayFromStr;
273///
274/// #[derive(Deserialize)]
275/// pub struct Ports {
276///     // same as BTreeMap<deser::adapters::Same, DisplayFromStr>
277///     #[deser(as = BTreeMap<_, DisplayFromStr>)]
278///     ports: BTreeMap<String, u16>,
279/// }
280/// ```
281pub struct Same;
282
283impl<'de, T: Deserialize<'de>> Deserialize<'de, T> for Same {
284    #[inline]
285    fn deserialize_into<'out>(
286        out: &'out mut Option<T>,
287        state: &mut State,
288    ) -> SinkHandle<'out, 'de> {
289        T::deserialize_into(out, state)
290    }
291
292    fn expecting() -> Cow<'static, str> {
293        T::expecting()
294    }
295
296    #[inline]
297    fn initial_value() -> Option<T> {
298        T::initial_value()
299    }
300
301    #[inline]
302    fn deserialize_update<'out>(value: &'out mut T, state: &mut State) -> SinkHandle<'out, 'de> {
303        T::deserialize_update(value, state)
304    }
305
306    #[inline]
307    fn __private_atom_into(
308        out: &mut Option<T>,
309        atom: Atom,
310        state: &mut State,
311    ) -> Result<(), Error> {
312        T::__private_atom_into(out, atom, state)
313    }
314
315    #[inline]
316    fn __private_borrowed_atom_into(
317        out: &mut Option<T>,
318        atom: Atom<'de>,
319        state: &mut State,
320    ) -> Result<(), Error> {
321        T::__private_borrowed_atom_into(out, atom, state)
322    }
323
324    #[inline]
325    fn __private_is_bytes() -> bool {
326        T::__private_is_bytes()
327    }
328
329    #[inline]
330    fn __private_vec_from_bytes(bytes: Vec<u8>) -> Option<Vec<T>> {
331        T::__private_vec_from_bytes(bytes)
332    }
333
334    #[inline]
335    fn __private_array_from_bytes<const N: usize>(bytes: &[u8]) -> Option<[T; N]> {
336        T::__private_array_from_bytes(bytes)
337    }
338
339    #[inline]
340    fn __private_atom_default() -> Option<T> {
341        T::__private_atom_default()
342    }
343
344    #[inline]
345    fn __private_inline_seq() -> Option<InlineSeq<T>> {
346        T::__private_inline_seq()
347    }
348
349    #[inline(always)]
350    fn __private_raw() -> Option<&'static crate::ext::RawFormatInfo> {
351        T::__private_raw()
352    }
353
354    fn describe_type(d: &mut dyn Describe) {
355        T::describe_type(d)
356    }
357
358    #[inline]
359    fn __private_collects() -> bool {
360        T::__private_collects()
361    }
362
363    #[inline]
364    fn __private_collect_into<'out>(
365        out: &'out mut Option<T>,
366        state: &mut State,
367    ) -> SinkHandle<'out, 'de> {
368        T::__private_collect_into(out, state)
369    }
370
371    #[inline]
372    fn __private_collect_update<'out>(
373        value: &'out mut T,
374        first: bool,
375        state: &mut State,
376    ) -> SinkHandle<'out, 'de> {
377        T::__private_collect_update(value, first, state)
378    }
379
380    #[inline]
381    fn __private_collect_empty() -> Option<T> {
382        T::__private_collect_empty()
383    }
384}
385
386impl<T: Serialize + ?Sized> Serialize<T> for Same {
387    #[inline]
388    fn serialize<'a>(value: &'a T, state: &mut State) -> Result<Emit<'a>, Error> {
389        T::serialize(value, state)
390    }
391
392    #[inline]
393    fn finish(value: &T, state: &mut State) -> Result<(), Error> {
394        T::finish(value, state)
395    }
396
397    #[inline]
398    fn is_optional(value: &T) -> bool {
399        T::is_optional(value)
400    }
401
402    #[inline]
403    fn container_shape(value: &T) -> ContainerShape {
404        T::container_shape(value)
405    }
406
407    fn describe(value: &T, d: &mut dyn Describe) {
408        T::describe(value, d)
409    }
410
411    #[inline]
412    fn __private_begin<'a>(value: &'a T, state: &mut State) -> Result<Begin<'a>, Error> {
413        T::__private_begin(value, state)
414    }
415
416    #[inline]
417    fn __private_is_plain() -> bool {
418        T::__private_is_plain()
419    }
420
421    #[inline]
422    fn __private_is_plain_value(value: &T) -> bool {
423        T::__private_is_plain_value(value)
424    }
425
426    #[inline]
427    fn __private_emit_plain(value: &T, sink: &mut dyn PlainSink) -> Result<(), Error> {
428        T::__private_emit_plain(value, sink)
429    }
430
431    #[inline]
432    fn __private_plain_cost(value: &T, budget: usize) -> Option<usize> {
433        T::__private_plain_cost(value, budget)
434    }
435
436    #[inline]
437    fn __private_slice_as_bytes(val: &[T]) -> Option<Cow<'_, [u8]>>
438    where
439        T: Sized,
440    {
441        T::__private_slice_as_bytes(val)
442    }
443}
444
445/// Holds a value that serializes and deserializes with an adapter.
446///
447/// This implements [`Serialize`] and [`Deserialize`] with the adapter `A`.
448/// It's useful to use adapters in places where `#[deser(as = ...)]` is not
449/// available.  The wrapper dereferences to the value.
450///
451/// ```
452/// use deser::adapters::{As, DisplayFromStr};
453///
454/// let values: Vec<As<u32, DisplayFromStr>> = vec![As::new(1), As::new(2)];
455/// assert_eq!(*values[0], 1);
456/// ```
457#[repr(transparent)]
458pub struct As<T, A> {
459    value: T,
460    _marker: PhantomData<fn() -> A>,
461}
462
463impl<T, A> As<T, A> {
464    /// Wraps a value.
465    #[inline(always)]
466    pub fn new(value: T) -> As<T, A> {
467        As {
468            value,
469            _marker: PhantomData,
470        }
471    }
472
473    /// Returns the wrapped value.
474    #[inline(always)]
475    pub fn into_inner(self) -> T {
476        self.value
477    }
478}
479
480impl<T, A> From<T> for As<T, A> {
481    fn from(value: T) -> As<T, A> {
482        As::new(value)
483    }
484}
485
486impl<T, A> Deref for As<T, A> {
487    type Target = T;
488
489    fn deref(&self) -> &T {
490        &self.value
491    }
492}
493
494impl<T, A> DerefMut for As<T, A> {
495    fn deref_mut(&mut self) -> &mut T {
496        &mut self.value
497    }
498}
499
500impl<T: fmt::Debug, A> fmt::Debug for As<T, A> {
501    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
502        fmt::Debug::fmt(&self.value, f)
503    }
504}
505
506impl<T: Clone, A> Clone for As<T, A> {
507    fn clone(&self) -> Self {
508        As::new(self.value.clone())
509    }
510}
511
512impl<T: Copy, A> Copy for As<T, A> {}
513
514impl<T: Default, A> Default for As<T, A> {
515    fn default() -> Self {
516        As::new(T::default())
517    }
518}
519
520impl<T: PartialEq, A> PartialEq for As<T, A> {
521    fn eq(&self, other: &Self) -> bool {
522        self.value == other.value
523    }
524}
525
526impl<T: Eq, A> Eq for As<T, A> {}
527
528impl<T: PartialOrd, A> PartialOrd for As<T, A> {
529    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
530        self.value.partial_cmp(&other.value)
531    }
532}
533
534impl<T: Ord, A> Ord for As<T, A> {
535    fn cmp(&self, other: &Self) -> Ordering {
536        self.value.cmp(&other.value)
537    }
538}
539
540impl<T: Hash, A> Hash for As<T, A> {
541    fn hash<H: Hasher>(&self, state: &mut H) {
542        self.value.hash(state)
543    }
544}
545
546impl<'de, T: Send, A: Deserialize<'de, T>> Deserialize<'de> for As<T, A> {
547    fn deserialize_into<'out>(
548        out: &'out mut Option<Self>,
549        state: &mut State,
550    ) -> SinkHandle<'out, 'de> {
551        crate::de::mapped::MappedSink::handle(
552            out,
553            OwnedSink::deserialize_as::<A>(state),
554            |value| Ok(As::new(value)),
555            state,
556        )
557    }
558
559    fn expecting() -> Cow<'static, str> {
560        A::expecting()
561    }
562
563    fn initial_value() -> Option<Self> {
564        A::initial_value().map(As::new)
565    }
566
567    #[inline]
568    fn __private_atom_into(
569        out: &mut Option<Self>,
570        atom: Atom,
571        state: &mut State,
572    ) -> Result<(), Error> {
573        let mut inner = None;
574        A::__private_atom_into(&mut inner, atom, state)?;
575        *out = inner.map(As::new);
576        Ok(())
577    }
578
579    #[inline]
580    fn __private_borrowed_atom_into(
581        out: &mut Option<Self>,
582        atom: Atom<'de>,
583        state: &mut State,
584    ) -> Result<(), Error> {
585        let mut inner = None;
586        A::__private_borrowed_atom_into(&mut inner, atom, state)?;
587        *out = inner.map(As::new);
588        Ok(())
589    }
590
591    #[inline]
592    fn __private_is_bytes() -> bool {
593        A::__private_is_bytes()
594    }
595
596    #[inline(always)]
597    fn __private_raw() -> Option<&'static crate::ext::RawFormatInfo> {
598        A::__private_raw()
599    }
600
601    fn describe_type(d: &mut dyn Describe) {
602        A::describe_type(d)
603    }
604
605    fn __private_vec_from_bytes(bytes: Vec<u8>) -> Option<Vec<Self>> {
606        A::__private_vec_from_bytes(bytes).map(|x| x.into_iter().map(As::new).collect())
607    }
608
609    fn __private_array_from_bytes<const N: usize>(bytes: &[u8]) -> Option<[Self; N]> {
610        A::__private_array_from_bytes::<N>(bytes).map(|x| x.map(As::new))
611    }
612}
613
614impl<T: Sync, A: Serialize<T>> Serialize for As<T, A> {
615    #[inline]
616    fn serialize<'a>(value: &'a Self, state: &mut State) -> Result<Emit<'a>, Error> {
617        A::serialize(&value.value, state)
618    }
619
620    #[inline]
621    fn finish(value: &Self, state: &mut State) -> Result<(), Error> {
622        A::finish(&value.value, state)
623    }
624
625    #[inline]
626    fn is_optional(value: &Self) -> bool {
627        A::is_optional(&value.value)
628    }
629
630    #[inline]
631    fn container_shape(value: &Self) -> ContainerShape {
632        A::container_shape(&value.value)
633    }
634
635    #[inline]
636    fn describe(value: &Self, d: &mut dyn Describe) {
637        A::describe(&value.value, d)
638    }
639
640    #[inline]
641    fn __private_begin<'a>(value: &'a Self, state: &mut State) -> Result<Begin<'a>, Error> {
642        A::__private_begin(&value.value, state)
643    }
644
645    #[inline]
646    fn __private_is_plain() -> bool {
647        A::__private_is_plain()
648    }
649
650    #[inline]
651    fn __private_is_plain_value(value: &Self) -> bool {
652        A::__private_is_plain_value(&value.value)
653    }
654
655    #[inline]
656    fn __private_emit_plain(value: &Self, sink: &mut dyn PlainSink) -> Result<(), Error> {
657        A::__private_emit_plain(&value.value, sink)
658    }
659
660    #[inline]
661    fn __private_plain_cost(value: &Self, budget: usize) -> Option<usize> {
662        A::__private_plain_cost(&value.value, budget)
663    }
664
665    #[inline]
666    fn __private_slice_as_bytes(val: &[Self]) -> Option<Cow<'_, [u8]>> {
667        // SAFETY: the wrapper is transparent over `T` (the marker is zero
668        // sized and has an alignment of one).
669        let val = unsafe { &*(val as *const [Self] as *const [T]) };
670        A::__private_slice_as_bytes(val)
671    }
672}