serde_untagged/
lib.rs

1//! [![github]](https://github.com/dtolnay/serde-untagged) [![crates-io]](https://crates.io/crates/serde-untagged) [![docs-rs]](https://docs.rs/serde-untagged)
2//!
3//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
4//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
5//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
6//!
7//! <br>
8//!
9//! This crate provides a Serde `Visitor` implementation that is useful for
10//! deserializing untagged enums.
11//!
12//! Untagged enum `Deserialize` impls look like this:
13//!
14//! ```
15//! use serde::de::{Deserialize, Deserializer};
16//! use serde_untagged::UntaggedEnumVisitor;
17//!
18//! # macro_rules! impl_deserialize {
19//! #     ($MyType:ty) => {
20//! impl<'de> Deserialize<'de> for $MyType {
21//!     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
22//!     where
23//!         D: Deserializer<'de>,
24//!     {
25//!         UntaggedEnumVisitor::new()
26//!             /*
27//!              *
28//!              */
29//!             .deserialize(deserializer)
30//!     }
31//! }
32//! #     };
33//! # }
34//! #
35//! # struct MyType;
36//! # impl_deserialize!(MyType);
37//! ```
38//!
39//! Inside the `/* ... */`, we list each type that the untagged enum needs to
40//! support deserializing from, giving a closure that turns the input into
41//! $MyType. The following types are supported:
42//!
43//! - bool
44//! - i8, i16, i32, i64, i128, u8, u16, u32, u64, u128
45//! - f32
46//! - f64
47//! - char
48//! - string
49//! - borrowed\_str
50//! - bytes
51//! - borrowed\_bytes
52//! - byte\_buf
53//! - unit
54//! - seq
55//! - map
56//!
57//! # Example: string or struct
58//!
59//! Cargo's `http.ssl-version` configuration supports deserialization from the
60//! following two representations:
61//!
62//! ```toml
63//! [http]
64//! ssl-version = "tlsv1.3"
65//! ```
66//!
67//! ```toml
68//! [http]
69//! ssl-version.min = "tlsv1.2"
70//! ssl-version.max = "tlsv1.3"
71//! ```
72//!
73//! ```
74//! use serde::de::{Deserialize, Deserializer};
75//! use serde_derive::Deserialize;
76//! use serde_untagged::UntaggedEnumVisitor;
77//!
78//! pub enum SslVersionConfig {
79//!     Single(String),
80//!     Range(SslVersionConfigRange),
81//! }
82//!
83//! impl<'de> Deserialize<'de> for SslVersionConfig {
84//!     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
85//!     where
86//!         D: Deserializer<'de>,
87//!     {
88//!         UntaggedEnumVisitor::new()
89//!             .string(|single| Ok(SslVersionConfig::Single(single.to_owned())))
90//!             .map(|map| map.deserialize().map(SslVersionConfig::Range))
91//!             .deserialize(deserializer)
92//!     }
93//! }
94//!
95//! #[derive(Deserialize)]
96//! pub struct SslVersionConfigRange {
97//!     pub min: Option<String>,
98//!     pub max: Option<String>,
99//! }
100//! ```
101//!
102//! # Example: unit variant or bool
103//!
104//! Cargo's LTO setting in profiles supports the 5 values `false`, `true`,
105//! `"fat"`, `"thin"`, and `"off"`.
106//!
107//! ```toml
108//! [profile.release]
109//! lto = "thin"
110//! ```
111//!
112//! ```
113//! use serde::de::{Deserialize, Deserializer, IntoDeserializer};
114//! use serde_derive::Deserialize;
115//! use serde_untagged::UntaggedEnumVisitor;
116//!
117//! pub enum LinkTimeOptimization {
118//!     Enabled(bool),
119//!     Enum(LinkTimeOptimizationString),
120//! }
121//!
122//! impl<'de> Deserialize<'de> for LinkTimeOptimization {
123//!     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
124//!     where
125//!         D: Deserializer<'de>,
126//!     {
127//!         UntaggedEnumVisitor::new()
128//!             .bool(|b| Ok(LinkTimeOptimization::Enabled(b)))
129//!             .string(|string| {
130//!                 let de = string.into_deserializer();
131//!                 LinkTimeOptimizationString::deserialize(de).map(LinkTimeOptimization::Enum)
132//!             })
133//!             .deserialize(deserializer)
134//!     }
135//! }
136//!
137//! #[derive(Deserialize)]
138//! #[serde(rename = "lowercase")]
139//! pub enum LinkTimeOptimizationString {
140//!     Fat,
141//!     Thin,
142//!     Off,
143//! }
144//! ```
145//!
146//! Since `lto = true` means the same thing as `lto = "fat"` to Cargo, there are
147//! really only 4 distinct options. This type could be implemented alternatively
148//! as:
149//!
150//! ```
151//! use serde::de::{Deserialize, Deserializer, Unexpected};
152//! use serde_untagged::UntaggedEnumVisitor;
153//!
154//! pub enum LinkTimeOptimization {
155//!     ThinLocal,  // false
156//!     Fat,        // true or "fat"
157//!     Thin,       // "thin"
158//!     Off,        // "off"
159//! }
160//!
161//! impl<'de> Deserialize<'de> for LinkTimeOptimization {
162//!     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
163//!     where
164//!         D: Deserializer<'de>,
165//!     {
166//!         UntaggedEnumVisitor::new()
167//!             .bool(|b| match b {
168//!                 false => Ok(LinkTimeOptimization::ThinLocal),
169//!                 true => Ok(LinkTimeOptimization::Fat),
170//!             })
171//!             .string(|string| match string {
172//!                 "fat" => Ok(LinkTimeOptimization::Fat),
173//!                 "thin" => Ok(LinkTimeOptimization::Thin),
174//!                 "off" => Ok(LinkTimeOptimization::Off),
175//!                 _ => Err(serde::de::Error::invalid_value(
176//!                     Unexpected::Str(string),
177//!                     &r#""fat" or "thin" or "off""#,
178//!                 )),
179//!             })
180//!             .deserialize(deserializer)
181//!     }
182//! }
183//! ```
184
185#![no_std]
186#![doc(html_root_url = "https://docs.rs/serde-untagged/0.1.9")]
187#![deny(unsafe_op_in_unsafe_fn)]
188#![allow(
189    clippy::doc_markdown,
190    clippy::elidable_lifetime_names,
191    clippy::enum_glob_use,
192    clippy::manual_assert,
193    clippy::manual_map,
194    clippy::missing_errors_doc,
195    clippy::missing_panics_doc,
196    clippy::must_use_candidate,
197    clippy::needless_lifetimes,
198    clippy::needless_pass_by_value,
199    clippy::new_without_default,
200    clippy::type_complexity
201)]
202#![allow(unknown_lints, mismatched_lifetime_syntaxes)]
203
204extern crate alloc;
205extern crate serde_core as serde;
206
207mod any;
208mod error;
209mod int;
210mod map;
211mod seed;
212mod seq;
213
214use crate::error::Error;
215use crate::map::Map;
216use crate::seq::Seq;
217use alloc::boxed::Box;
218use alloc::vec::Vec;
219use core::fmt::{self, Display};
220use core::marker::PhantomData;
221use serde::de::{Deserializer, Expected, MapAccess, SeqAccess, Unexpected, Visitor};
222
223pub mod de {
224    pub use crate::error::Error;
225    pub use crate::map::Map;
226    pub use crate::seq::Seq;
227}
228
229pub struct UntaggedEnumVisitor<'closure, 'de, Value> {
230    expecting: Option<Box<dyn Display + 'closure>>,
231    visit_bool: Option<Box<dyn FnOnce(bool) -> Result<Value, Error> + 'closure>>,
232    visit_i8: Option<Box<dyn FnOnce(i8) -> Result<Value, Error> + 'closure>>,
233    visit_i16: Option<Box<dyn FnOnce(i16) -> Result<Value, Error> + 'closure>>,
234    visit_i32: Option<Box<dyn FnOnce(i32) -> Result<Value, Error> + 'closure>>,
235    visit_i64: Option<Box<dyn FnOnce(i64) -> Result<Value, Error> + 'closure>>,
236    visit_i128: Option<Box<dyn FnOnce(i128) -> Result<Value, Error> + 'closure>>,
237    visit_u8: Option<Box<dyn FnOnce(u8) -> Result<Value, Error> + 'closure>>,
238    visit_u16: Option<Box<dyn FnOnce(u16) -> Result<Value, Error> + 'closure>>,
239    visit_u32: Option<Box<dyn FnOnce(u32) -> Result<Value, Error> + 'closure>>,
240    visit_u64: Option<Box<dyn FnOnce(u64) -> Result<Value, Error> + 'closure>>,
241    visit_u128: Option<Box<dyn FnOnce(u128) -> Result<Value, Error> + 'closure>>,
242    visit_f32: Option<Box<dyn FnOnce(f32) -> Result<Value, Error> + 'closure>>,
243    visit_f64: Option<Box<dyn FnOnce(f64) -> Result<Value, Error> + 'closure>>,
244    visit_char: Option<Box<dyn FnOnce(char) -> Result<Value, Error> + 'closure>>,
245    visit_str: Option<Box<dyn FnOnce(&str) -> Result<Value, Error> + 'closure>>,
246    visit_borrowed_str: Option<Box<dyn FnOnce(&'de str) -> Result<Value, Error> + 'closure>>,
247    visit_bytes: Option<Box<dyn FnOnce(&[u8]) -> Result<Value, Error> + 'closure>>,
248    visit_borrowed_bytes: Option<Box<dyn FnOnce(&'de [u8]) -> Result<Value, Error> + 'closure>>,
249    visit_byte_buf: Option<Box<dyn FnOnce(Vec<u8>) -> Result<Value, Error> + 'closure>>,
250    visit_none: Option<Box<dyn FnOnce() -> Result<Value, Error> + 'closure>>,
251    visit_unit: Option<Box<dyn FnOnce() -> Result<Value, Error> + 'closure>>,
252    visit_seq:
253        Option<Box<dyn for<'access> FnOnce(Seq<'access, 'de>) -> Result<Value, Error> + 'closure>>,
254    visit_map:
255        Option<Box<dyn for<'access> FnOnce(Map<'access, 'de>) -> Result<Value, Error> + 'closure>>,
256}
257
258impl<'closure, 'de, Value> UntaggedEnumVisitor<'closure, 'de, Value> {
259    pub fn new() -> Self {
260        UntaggedEnumVisitor {
261            expecting: None,
262            visit_bool: None,
263            visit_i8: None,
264            visit_i16: None,
265            visit_i32: None,
266            visit_i64: None,
267            visit_i128: None,
268            visit_u8: None,
269            visit_u16: None,
270            visit_u32: None,
271            visit_u64: None,
272            visit_u128: None,
273            visit_f32: None,
274            visit_f64: None,
275            visit_char: None,
276            visit_str: None,
277            visit_borrowed_str: None,
278            visit_bytes: None,
279            visit_borrowed_bytes: None,
280            visit_byte_buf: None,
281            visit_none: None,
282            visit_unit: None,
283            visit_seq: None,
284            visit_map: None,
285        }
286    }
287
288    /// Provide a message stating what data this untagged enum expects to
289    /// receive.
290    ///
291    /// This is used in error messages when deserialization fails. The message
292    /// should complete the sentence _"This Visitor expects to receive …"_, for
293    /// example the message could be _"an integer, or map containing the keys
294    /// 'min' and 'max'"_. The message should not be capitalized and should not
295    /// end with a period.
296    ///
297    /// ```
298    /// # use serde::de::Deserializer;
299    /// # use serde_untagged::UntaggedEnumVisitor;
300    /// #
301    /// # fn deserialize<'de, D>(deserializer: D) -> Result<(), D::Error>
302    /// # where
303    /// #     D: Deserializer<'de>,
304    /// # {
305    /// #     let max = 1;
306    /// UntaggedEnumVisitor::new()
307    ///     .expecting(format_args!("a string or number between 0 and {max}"))
308    ///     /* ... */
309    ///     .deserialize(deserializer)
310    /// # }
311    /// ```
312    ///
313    /// If `expecting` is not called, then `UntaggedEnumVisitor` constructs a
314    /// default message based on the set of closures given to it.
315    ///
316    /// ```
317    /// # use serde::de::Deserializer;
318    /// # use serde_untagged::UntaggedEnumVisitor;
319    /// #
320    /// # macro_rules! methods {
321    /// #     ($($construct:ident)::*() $(.$name:ident(|$arg:ident| ...))*) => {
322    /// #         $($construct)::*()
323    /// #         $(
324    /// #             .$name(|$arg| unimplemented!())
325    /// #         )*
326    /// #     };
327    /// # }
328    /// #
329    /// # fn deserialize<'de, D>(deserializer: D) -> Result<(), D::Error>
330    /// # where
331    /// #     D: Deserializer<'de>,
332    /// # {
333    /// # methods!(
334    /// // by default, this enum expects "a boolean, string, or map"
335    /// UntaggedEnumVisitor::new()
336    ///     .bool(|b| ...)
337    ///     .string(|s| ...)
338    ///     .map(|m| ...)
339    /// # )
340    ///     .deserialize(deserializer)
341    /// # }
342    /// ```
343    #[must_use]
344    pub fn expecting(mut self, expecting: impl Display + 'closure) -> Self {
345        if self.expecting.is_some() {
346            panic!("UntaggedEnumVisitor::expecting already set");
347        }
348        self.expecting = Some(Box::new(expecting));
349        self
350    }
351
352    #[must_use]
353    pub fn bool(mut self, visit: impl FnOnce(bool) -> Result<Value, Error> + 'closure) -> Self {
354        if self.visit_bool.is_some() {
355            panic!("UntaggedEnumVisitor::bool already set");
356        }
357        self.visit_bool = Some(Box::new(visit));
358        self
359    }
360
361    #[must_use]
362    pub fn i8(mut self, visit: impl FnOnce(i8) -> Result<Value, Error> + 'closure) -> Self {
363        if self.visit_i8.is_some() {
364            panic!("UntaggedEnumVisitor::i8 already set");
365        }
366        self.visit_i8 = Some(Box::new(visit));
367        self
368    }
369
370    #[must_use]
371    pub fn i16(mut self, visit: impl FnOnce(i16) -> Result<Value, Error> + 'closure) -> Self {
372        if self.visit_i16.is_some() {
373            panic!("UntaggedEnumVisitor::i16 already set");
374        }
375        self.visit_i16 = Some(Box::new(visit));
376        self
377    }
378
379    #[must_use]
380    pub fn i32(mut self, visit: impl FnOnce(i32) -> Result<Value, Error> + 'closure) -> Self {
381        if self.visit_i32.is_some() {
382            panic!("UntaggedEnumVisitor::i32 already set");
383        }
384        self.visit_i32 = Some(Box::new(visit));
385        self
386    }
387
388    #[must_use]
389    pub fn i64(mut self, visit: impl FnOnce(i64) -> Result<Value, Error> + 'closure) -> Self {
390        if self.visit_i64.is_some() {
391            panic!("UntaggedEnumVisitor::i64 already set");
392        }
393        self.visit_i64 = Some(Box::new(visit));
394        self
395    }
396
397    #[must_use]
398    pub fn i128(mut self, visit: impl FnOnce(i128) -> Result<Value, Error> + 'closure) -> Self {
399        if self.visit_i128.is_some() {
400            panic!("UntaggedEnumVisitor::i128 already set");
401        }
402        self.visit_i128 = Some(Box::new(visit));
403        self
404    }
405
406    #[must_use]
407    pub fn u8(mut self, visit: impl FnOnce(u8) -> Result<Value, Error> + 'closure) -> Self {
408        if self.visit_u8.is_some() {
409            panic!("UntaggedEnumVisitor::u8 already set");
410        }
411        self.visit_u8 = Some(Box::new(visit));
412        self
413    }
414
415    #[must_use]
416    pub fn u16(mut self, visit: impl FnOnce(u16) -> Result<Value, Error> + 'closure) -> Self {
417        if self.visit_u16.is_some() {
418            panic!("UntaggedEnumVisitor::u16 already set");
419        }
420        self.visit_u16 = Some(Box::new(visit));
421        self
422    }
423
424    #[must_use]
425    pub fn u32(mut self, visit: impl FnOnce(u32) -> Result<Value, Error> + 'closure) -> Self {
426        if self.visit_u32.is_some() {
427            panic!("UntaggedEnumVisitor::u32 already set");
428        }
429        self.visit_u32 = Some(Box::new(visit));
430        self
431    }
432
433    #[must_use]
434    pub fn u64(mut self, visit: impl FnOnce(u64) -> Result<Value, Error> + 'closure) -> Self {
435        if self.visit_u64.is_some() {
436            panic!("UntaggedEnumVisitor::u64 already set");
437        }
438        self.visit_u64 = Some(Box::new(visit));
439        self
440    }
441
442    #[must_use]
443    pub fn u128(mut self, visit: impl FnOnce(u128) -> Result<Value, Error> + 'closure) -> Self {
444        if self.visit_u128.is_some() {
445            panic!("UntaggedEnumVisitor::u128 already set");
446        }
447        self.visit_u128 = Some(Box::new(visit));
448        self
449    }
450
451    #[must_use]
452    pub fn f32(mut self, visit: impl FnOnce(f32) -> Result<Value, Error> + 'closure) -> Self {
453        if self.visit_f32.is_some() {
454            panic!("UntaggedEnumVisitor::f32 already set");
455        }
456        self.visit_f32 = Some(Box::new(visit));
457        self
458    }
459
460    #[must_use]
461    pub fn f64(mut self, visit: impl FnOnce(f64) -> Result<Value, Error> + 'closure) -> Self {
462        if self.visit_f64.is_some() {
463            panic!("UntaggedEnumVisitor::f64 already set");
464        }
465        self.visit_f64 = Some(Box::new(visit));
466        self
467    }
468
469    #[must_use]
470    pub fn char(mut self, visit: impl FnOnce(char) -> Result<Value, Error> + 'closure) -> Self {
471        if self.visit_char.is_some() {
472            panic!("UntaggedEnumVisitor::char already set");
473        }
474        self.visit_char = Some(Box::new(visit));
475        self
476    }
477
478    #[must_use]
479    pub fn string(mut self, visit: impl FnOnce(&str) -> Result<Value, Error> + 'closure) -> Self {
480        if self.visit_str.is_some() {
481            panic!("UntaggedEnumVisitor::string already set");
482        }
483        self.visit_str = Some(Box::new(visit));
484        self
485    }
486
487    #[must_use]
488    pub fn borrowed_str(
489        mut self,
490        visit: impl FnOnce(&'de str) -> Result<Value, Error> + 'closure,
491    ) -> Self {
492        if self.visit_borrowed_str.is_some() {
493            panic!("UntaggedEnumVisitor::borrowed_str already set");
494        }
495        self.visit_borrowed_str = Some(Box::new(visit));
496        self
497    }
498
499    #[must_use]
500    pub fn bytes(mut self, visit: impl FnOnce(&[u8]) -> Result<Value, Error> + 'closure) -> Self {
501        if self.visit_bytes.is_some() {
502            panic!("UntaggedEnumVisitor::bytes already set");
503        }
504        self.visit_bytes = Some(Box::new(visit));
505        self
506    }
507
508    #[must_use]
509    pub fn borrowed_bytes(
510        mut self,
511        visit: impl FnOnce(&'de [u8]) -> Result<Value, Error> + 'closure,
512    ) -> Self {
513        if self.visit_borrowed_bytes.is_some() {
514            panic!("UntaggedEnumVisitor::borrowed_bytes already set");
515        }
516        self.visit_borrowed_bytes = Some(Box::new(visit));
517        self
518    }
519
520    #[must_use]
521    pub fn byte_buf(
522        mut self,
523        visit: impl FnOnce(Vec<u8>) -> Result<Value, Error> + 'closure,
524    ) -> Self {
525        if self.visit_byte_buf.is_some() {
526            panic!("UntaggedEnumVisitor::byte_buf already set");
527        }
528        self.visit_byte_buf = Some(Box::new(visit));
529        self
530    }
531
532    #[must_use]
533    pub fn none(mut self, visit: impl FnOnce() -> Result<Value, Error> + 'closure) -> Self {
534        if self.visit_none.is_some() {
535            panic!("UntaggedEnumVisitor::none already set");
536        }
537        self.visit_none = Some(Box::new(visit));
538        self
539    }
540
541    #[must_use]
542    pub fn unit(mut self, visit: impl FnOnce() -> Result<Value, Error> + 'closure) -> Self {
543        if self.visit_unit.is_some() {
544            panic!("UntaggedEnumVisitor::unit already set");
545        }
546        self.visit_unit = Some(Box::new(visit));
547        self
548    }
549
550    /// Deserialize a sequence. The argument implements
551    /// [`serde::de::SeqAccess`].
552    #[must_use]
553    pub fn seq(
554        mut self,
555        visit: impl for<'access> FnOnce(Seq<'access, 'de>) -> Result<Value, Error> + 'closure,
556    ) -> Self {
557        if self.visit_seq.is_some() {
558            panic!("UntaggedEnumVisitor::seq already set");
559        }
560        self.visit_seq = Some(Box::new(visit));
561        self
562    }
563
564    /// Deserialize a key-value map. The argument implements
565    /// [`serde::de::MapAccess`].
566    ///
567    /// ```
568    /// # use serde::de::Deserializer;
569    /// use serde::de::MapAccess;
570    /// use serde_untagged::UntaggedEnumVisitor;
571    /// use std::collections::HashMap;
572    ///
573    /// # fn deserialize<'de, D>(deserializer: D) -> Result<HashMap<i32, i32>, D::Error>
574    /// # where
575    /// #     D: Deserializer<'de>,
576    /// # {
577    /// UntaggedEnumVisitor::new()
578    ///     .map(|mut map| {
579    ///         let mut hashmap = HashMap::new();
580    ///         while let Some(key) = map.next_key()? {
581    ///             let value = map.next_value()?;
582    ///             hashmap.insert(key, value);
583    ///         }
584    ///         Ok(hashmap)
585    ///     })
586    ///     .deserialize(deserializer)
587    /// # }
588    /// ```
589    ///
590    /// If you need to inspect the contents of the map to decide how to
591    /// deserialize, you can buffer it into some kind of `Value` and deserialize
592    /// from there.
593    ///
594    /// ```
595    /// # use serde::de::{Deserialize, Deserializer};
596    /// # use serde_untagged::UntaggedEnumVisitor;
597    /// #
598    /// enum Response {
599    ///     // {"failure":"..."}
600    ///     Failure(String),
601    ///     // Anything else. {"ok":200}
602    ///     Success(serde_json::Value),
603    /// }
604    ///
605    /// impl<'de> Deserialize<'de> for Response {
606    ///     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
607    ///     where
608    ///         D: Deserializer<'de>,
609    ///     {
610    ///         UntaggedEnumVisitor::new()
611    ///             .map(|map| {
612    ///                 let value: serde_json::Value = map.deserialize()?;
613    ///                 if let Some(failure) = value["failure"].as_str() {
614    ///                     Ok(Response::Failure(failure.to_owned()))
615    ///                 } else {
616    ///                     Ok(Response::Success(value))
617    ///                 }
618    ///             })
619    ///             .deserialize(deserializer)
620    ///     }
621    /// }
622    /// ```
623    #[must_use]
624    pub fn map(
625        mut self,
626        visit: impl for<'access> FnOnce(Map<'access, 'de>) -> Result<Value, Error> + 'closure,
627    ) -> Self {
628        if self.visit_map.is_some() {
629            panic!("UntaggedEnumVisitor::map already set");
630        }
631        self.visit_map = Some(Box::new(visit));
632        self
633    }
634
635    pub fn deserialize<D>(self, deserializer: D) -> Result<Value, D::Error>
636    where
637        D: Deserializer<'de>,
638    {
639        deserializer.deserialize_any(self)
640    }
641}
642
643impl<'closure, 'de, Value> Visitor<'de> for UntaggedEnumVisitor<'closure, 'de, Value> {
644    type Value = Value;
645
646    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
647        if let Some(expecting) = &self.expecting {
648            return expecting.fmt(formatter);
649        }
650
651        // "a string or array"
652        // "an integer, string, or map"
653        let mut message = Expecting::new(formatter);
654        if self.visit_bool.is_some() {
655            message.push("a", "boolean")?;
656        }
657        if self.visit_i8.is_some()
658            || self.visit_i16.is_some()
659            || self.visit_i32.is_some()
660            || self.visit_i64.is_some()
661            || self.visit_i128.is_some()
662            || self.visit_u8.is_some()
663            || self.visit_u16.is_some()
664            || self.visit_u32.is_some()
665            || self.visit_u64.is_some()
666            || self.visit_u128.is_some()
667        {
668            message.push("an", "integer")?;
669        }
670        if self.visit_f32.is_some() || self.visit_f64.is_some() {
671            message.push("a", "float")?;
672        }
673        if self.visit_char.is_some() {
674            message.push("a", "character")?;
675        }
676        if self.visit_str.is_some() {
677            message.push("a", "string")?;
678        }
679        if self.visit_borrowed_str.is_some() && self.visit_str.is_none() {
680            message.push("a", "borrowed string")?;
681        }
682        if self.visit_bytes.is_some()
683            || self.visit_borrowed_bytes.is_some()
684            || self.visit_byte_buf.is_some()
685        {
686            message.push("a", "byte array")?;
687        }
688        if self.visit_unit.is_some() || self.visit_none.is_some() {
689            message.push("", "null")?;
690        }
691        if self.visit_seq.is_some() {
692            message.push("an", "array")?;
693        }
694        if self.visit_map.is_some() {
695            message.push("a", "map")?;
696        }
697        message.flush()
698    }
699
700    fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
701    where
702        E: serde::de::Error,
703    {
704        if let Some(visit_bool) = self.visit_bool {
705            visit_bool(v).map_err(error::unerase)
706        } else {
707            DefaultVisitor::new(&self).visit_bool(v)
708        }
709    }
710
711    fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E>
712    where
713        E: serde::de::Error,
714    {
715        use crate::int::IntKind::*;
716        self.dispatch_integer(v, [I8, I16, I32, I64, I128, U8, U16, U32, U64, U128])
717    }
718
719    fn visit_i16<E>(self, v: i16) -> Result<Self::Value, E>
720    where
721        E: serde::de::Error,
722    {
723        use crate::int::IntKind::*;
724        self.dispatch_integer(v, [I16, I32, I64, I128, I8, U8, U16, U32, U64, U128])
725    }
726
727    fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
728    where
729        E: serde::de::Error,
730    {
731        use crate::int::IntKind::*;
732        self.dispatch_integer(v, [I32, I64, I128, I8, I16, U8, U16, U32, U64, U128])
733    }
734
735    fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
736    where
737        E: serde::de::Error,
738    {
739        use crate::int::IntKind::*;
740        self.dispatch_integer(v, [I64, I128, I8, I16, I32, U8, U16, U32, U64, U128])
741    }
742
743    fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
744    where
745        E: serde::de::Error,
746    {
747        use crate::int::IntKind::*;
748        self.dispatch_integer(v, [I128, I8, I16, I32, I64, U8, U16, U32, U64, U128])
749    }
750
751    fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
752    where
753        E: serde::de::Error,
754    {
755        use crate::int::IntKind::*;
756        self.dispatch_integer(v, [U8, U16, U32, U64, U128, I8, I16, I32, I64, I128])
757    }
758
759    fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E>
760    where
761        E: serde::de::Error,
762    {
763        use crate::int::IntKind::*;
764        self.dispatch_integer(v, [U16, U32, U64, U128, U8, I8, I16, I32, I64, I128])
765    }
766
767    fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
768    where
769        E: serde::de::Error,
770    {
771        use crate::int::IntKind::*;
772        self.dispatch_integer(v, [U32, U64, U128, U8, U16, I8, I16, I32, I64, I128])
773    }
774
775    fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
776    where
777        E: serde::de::Error,
778    {
779        use crate::int::IntKind::*;
780        self.dispatch_integer(v, [U64, U128, U8, U16, U32, I8, I16, I32, I64, I128])
781    }
782
783    fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
784    where
785        E: serde::de::Error,
786    {
787        use crate::int::IntKind::*;
788        self.dispatch_integer(v, [U128, U8, U16, U32, U64, I8, I16, I32, I64, I128])
789    }
790
791    fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E>
792    where
793        E: serde::de::Error,
794    {
795        if let Some(visit_f32) = self.visit_f32 {
796            visit_f32(v).map_err(error::unerase)
797        } else {
798            self.visit_f64(f64::from(v))
799        }
800    }
801
802    fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
803    where
804        E: serde::de::Error,
805    {
806        if let Some(visit_f64) = self.visit_f64 {
807            visit_f64(v).map_err(error::unerase)
808        } else {
809            DefaultVisitor::new(&self).visit_f64(v)
810        }
811    }
812
813    fn visit_char<E>(self, v: char) -> Result<Self::Value, E>
814    where
815        E: serde::de::Error,
816    {
817        if let Some(visit_char) = self.visit_char {
818            visit_char(v).map_err(error::unerase)
819        } else if self.visit_str.is_some() {
820            self.visit_str(v.encode_utf8(&mut [0u8; 4]))
821        } else {
822            Err(E::invalid_type(Unexpected::Char(v), &self))
823        }
824    }
825
826    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
827    where
828        E: serde::de::Error,
829    {
830        if let Some(visit_str) = self.visit_str {
831            visit_str(v).map_err(error::unerase)
832        } else {
833            DefaultVisitor::new(&self).visit_str(v)
834        }
835    }
836
837    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
838    where
839        E: serde::de::Error,
840    {
841        if let Some(visit_borrowed_str) = self.visit_borrowed_str {
842            visit_borrowed_str(v).map_err(error::unerase)
843        } else {
844            self.visit_str(v)
845        }
846    }
847
848    fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
849    where
850        E: serde::de::Error,
851    {
852        if let Some(visit_bytes) = self.visit_bytes {
853            visit_bytes(v).map_err(error::unerase)
854        } else {
855            DefaultVisitor::new(&self).visit_bytes(v)
856        }
857    }
858
859    fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
860    where
861        E: serde::de::Error,
862    {
863        if let Some(visit_borrowed_bytes) = self.visit_borrowed_bytes {
864            visit_borrowed_bytes(v).map_err(error::unerase)
865        } else {
866            self.visit_bytes(v)
867        }
868    }
869
870    fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
871    where
872        E: serde::de::Error,
873    {
874        if let Some(visit_byte_buf) = self.visit_byte_buf {
875            visit_byte_buf(v).map_err(error::unerase)
876        } else {
877            self.visit_bytes(&v)
878        }
879    }
880
881    fn visit_none<E>(self) -> Result<Self::Value, E>
882    where
883        E: serde::de::Error,
884    {
885        if let Some(visit_none) = self.visit_none {
886            visit_none().map_err(error::unerase)
887        } else {
888            DefaultVisitor::new(&self).visit_none()
889        }
890    }
891
892    fn visit_unit<E>(self) -> Result<Self::Value, E>
893    where
894        E: serde::de::Error,
895    {
896        if let Some(visit_unit) = self.visit_unit {
897            visit_unit().map_err(error::unerase)
898        } else {
899            DefaultVisitor::new(&self).visit_unit()
900        }
901    }
902
903    fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
904    where
905        A: SeqAccess<'de>,
906    {
907        if let Some(visit_seq) = self.visit_seq {
908            visit_seq(Seq::new(seq)).map_err(error::unerase)
909        } else {
910            DefaultVisitor::new(&self).visit_seq(seq)
911        }
912    }
913
914    fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
915    where
916        A: MapAccess<'de>,
917    {
918        if let Some(visit_map) = self.visit_map {
919            visit_map(Map::new(map)).map_err(error::unerase)
920        } else {
921            DefaultVisitor::new(&self).visit_map(map)
922        }
923    }
924}
925
926struct DefaultVisitor<'a, E, T> {
927    expected: &'a E,
928    value: PhantomData<T>,
929}
930
931impl<'a, E, T> DefaultVisitor<'a, E, T> {
932    fn new(expected: &'a E) -> Self {
933        DefaultVisitor {
934            expected,
935            value: PhantomData,
936        }
937    }
938}
939
940impl<'a, 'de, V, T> Visitor<'de> for DefaultVisitor<'a, V, T>
941where
942    V: Expected,
943{
944    type Value = T;
945
946    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
947        self.expected.fmt(formatter)
948    }
949}
950
951struct Expecting<'e, 'a> {
952    formatter: &'e mut fmt::Formatter<'a>,
953    count: usize,
954    last: Option<&'e str>,
955}
956
957impl<'e, 'a> Expecting<'e, 'a> {
958    fn new(formatter: &'e mut fmt::Formatter<'a>) -> Self {
959        Expecting {
960            formatter,
961            count: 0,
962            last: None,
963        }
964    }
965
966    fn push(&mut self, article: &str, item: &'e str) -> fmt::Result {
967        self.count += 1;
968        if self.count == 1 {
969            if !article.is_empty() {
970                self.formatter.write_str(article)?;
971                self.formatter.write_str(" ")?;
972            }
973            self.formatter.write_str(item)?;
974        } else {
975            if let Some(last) = self.last.take() {
976                self.formatter.write_str(", ")?;
977                self.formatter.write_str(last)?;
978            }
979            self.last = Some(item);
980        }
981        Ok(())
982    }
983
984    fn flush(&mut self) -> fmt::Result {
985        if self.count == 0 {
986            self.formatter.write_str("unspecified") // ??
987        } else if let Some(last) = self.last.take() {
988            self.formatter.write_str(" or ")?;
989            self.formatter.write_str(last)
990        } else {
991            Ok(())
992        }
993    }
994}