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}