[go: up one dir, main page]

docopt/
dopt.rs

1use std::collections::HashMap;
2use std::error::Error as StdError;
3use std::fmt::{self, Debug};
4use std::io::{self, Write};
5use std::str::FromStr;
6use std::result;
7
8use lazy_static::lazy_static;
9use regex::{Captures, Regex};
10use serde::de;
11use serde::de::IntoDeserializer;
12
13use crate::parse::Parser;
14use crate::synonym::SynonymMap;
15
16use self::Value::{Switch, Counted, Plain, List};
17use self::Error::{Usage, Argv, NoMatch, Deserialize, WithProgramUsage, Help, Version};
18
19use crate::cap_or_empty;
20
21/// Represents the different types of Docopt errors.
22///
23/// This error type has a lot of variants. In the common case, you probably
24/// don't care why Docopt has failed, and would rather just quit the program
25/// and show an error message instead. The `exit` method defined on the `Error`
26/// type will do just that. It will also set the exit code appropriately
27/// (no error for `--help` or `--version`, but an error code for bad usage,
28/// bad argv, no match or bad decode).
29///
30/// ### Example
31///
32/// Generally, you want to parse the usage string, try to match the argv
33/// and then quit the program if there was an error reported at any point
34/// in that process. This can be achieved like so:
35///
36/// ```no_run
37/// use docopt::Docopt;
38///
39/// const USAGE: &'static str = "
40/// Usage: ...
41/// ";
42///
43/// let args = Docopt::new(USAGE)
44///                   .and_then(|d| d.parse())
45///                   .unwrap_or_else(|e| e.exit());
46/// ```
47#[derive(Debug)]
48pub enum Error {
49    /// Parsing the usage string failed.
50    ///
51    /// This error can only be triggered by the programmer, i.e., the writer
52    /// of the Docopt usage string. This error is usually indicative of a bug
53    /// in your program.
54    Usage(String),
55
56    /// Parsing the argv specified failed.
57    ///
58    /// The payload is a string describing why the arguments provided could not
59    /// be parsed.
60    ///
61    /// This is distinct from `NoMatch` because it will catch errors like
62    /// using flags that aren't defined in the usage string.
63    Argv(String),
64
65    /// The given argv parsed successfully, but it did not match any example
66    /// usage of the program.
67    ///
68    /// Regrettably, there is no descriptive message describing *why* the
69    /// given argv didn't match any of the usage strings.
70    NoMatch,
71
72    /// This indicates a problem deserializing a successful argv match into a
73    /// deserializable value.
74    Deserialize(String),
75
76    /// Parsing failed, and the program usage should be printed next to the
77    /// failure message. Typically this wraps `Argv` and `NoMatch` errors.
78    WithProgramUsage(Box<Error>, String),
79
80    /// Decoding or parsing failed because the command line specified that the
81    /// help message should be printed.
82    Help,
83
84    /// Decoding or parsing failed because the command line specified that the
85    /// version should be printed
86    ///
87    /// The version is included as a payload to this variant.
88    Version(String),
89}
90
91impl Error {
92    /// Return whether this was a fatal error or not.
93    ///
94    /// Non-fatal errors include requests to print the help or version
95    /// information of a program, while fatal errors include those such as
96    /// failing to decode or parse.
97    pub fn fatal(&self) -> bool {
98        match *self {
99            Help | Version(..) => false,
100            Usage(..) | Argv(..) | NoMatch | Deserialize(..) => true,
101            WithProgramUsage(ref b, _) => b.fatal(),
102        }
103    }
104
105    /// Print this error and immediately exit the program.
106    ///
107    /// If the error is non-fatal (e.g., `Help` or `Version`), then the
108    /// error is printed to stdout and the exit status will be `0`. Otherwise,
109    /// when the error is fatal, the error is printed to stderr and the
110    /// exit status will be `1`.
111    pub fn exit(&self) -> ! {
112        if self.fatal() {
113            werr!("{}\n", self);
114            ::std::process::exit(1)
115        } else {
116            let _ = writeln!(&mut io::stdout(), "{}", self);
117            ::std::process::exit(0)
118        }
119    }
120}
121
122type Result<T> = result::Result<T, Error>;
123
124impl fmt::Display for Error {
125    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
126        match *self {
127            WithProgramUsage(ref other, ref usage) => {
128                let other = other.to_string();
129                if other.is_empty() {
130                    write!(f, "{}", usage)
131                } else {
132                    write!(f, "{}\n\n{}", other, usage)
133                }
134            }
135            Help => write!(f, ""),
136            NoMatch => write!(f, "Invalid arguments."),
137            Usage(ref s) |
138            Argv(ref s) |
139            Deserialize(ref s) |
140            Version(ref s) => write!(f, "{}", s),
141        }
142    }
143}
144
145impl StdError for Error {
146    fn source(&self) -> Option<&(dyn StdError + 'static)> {
147        match *self {
148            WithProgramUsage(ref cause, _) => Some(&**cause),
149            _ => None,
150        }
151    }
152}
153
154impl de::Error for Error {
155    fn custom<T: fmt::Display>(msg: T) -> Self {
156        Error::Deserialize(msg.to_string())
157    }
158}
159
160/// The main Docopt type, which is constructed with a Docopt usage string.
161///
162/// This can be used to match command line arguments to produce a `ArgvMap`.
163#[derive(Clone, Debug)]
164pub struct Docopt {
165    p: Parser,
166    argv: Option<Vec<String>>,
167    options_first: bool,
168    help: bool,
169    version: Option<String>,
170}
171
172impl Docopt {
173    /// Parse the Docopt usage string given.
174    ///
175    /// The `Docopt` value returned may be used immediately to parse command
176    /// line arguments with a default configuration.
177    ///
178    /// If there was a problem parsing the usage string, a `Usage` error
179    /// is returned.
180    pub fn new<S>(usage: S) -> Result<Docopt>
181            where S: ::std::ops::Deref<Target=str> {
182        Parser::new(usage.deref())
183               .map_err(Usage)
184               .map(|p| Docopt {
185                   p: p,
186                   argv: None,
187                   options_first: false,
188                   help: true,
189                   version: None,
190                })
191    }
192
193    /// Parse and deserialize the given argv.
194    ///
195    /// This is a convenience method for
196    /// `parse().and_then(|vals| vals.deserialize())`.
197    ///
198    /// For details on how decoding works, please see the documentation for
199    /// `ArgvMap`.
200    pub fn deserialize<'a, 'de: 'a, D>(&'a self) -> Result<D>
201        where D: de::Deserialize<'de>
202    {
203        self.parse().and_then(|vals| vals.deserialize())
204    }
205
206    /// Parse command line arguments and try to match them against a usage
207    /// pattern specified in the Docopt string.
208    ///
209    /// If there is a match, then an `ArgvMap` is returned, which maps
210    /// flags, commands and arguments to values.
211    ///
212    /// If parsing the command line arguments fails, then an `Argv` error is
213    /// returned. If parsing succeeds but there is no match, then a `NoMatch`
214    /// error is returned. Both of these errors are always returned inside a
215    /// `WithProgramUsage` error.
216    ///
217    /// If special handling of `help` or `version` is enabled (the former is
218    /// enabled by default), then `Help` or `Version` errors are returned
219    /// if `--help` or `--version` is present.
220    pub fn parse(&self) -> Result<ArgvMap> {
221        let argv = self.argv.clone().unwrap_or_else(Docopt::get_argv);
222        let vals =
223            self.p.parse_argv(argv, self.options_first)
224                .map_err(|s| self.err_with_usage(Argv(s)))
225                .and_then(|argv|
226                    match self.p.matches(&argv) {
227                        Some(m) => Ok(ArgvMap { map: m }),
228                        None => Err(self.err_with_usage(NoMatch)),
229                    })?;
230        if self.help && vals.get_bool("--help") {
231            return Err(self.err_with_full_doc(Help));
232        }
233        match self.version {
234            Some(ref v) if vals.get_bool("--version") => {
235                return Err(Version(v.clone()))
236            }
237            _ => {},
238        }
239        Ok(vals)
240    }
241
242    /// Set the argv to be used for Docopt parsing.
243    ///
244    /// By default, when no argv is set, and it is automatically taken from
245    /// `std::env::args()`.
246    ///
247    /// The `argv` given *must* be the full set of `argv` passed to the
248    /// program. e.g., `["cp", "src", "dest"]` is right while `["src", "dest"]`
249    /// is wrong.
250    pub fn argv<I, S>(mut self, argv: I) -> Docopt
251               where I: IntoIterator<Item=S>, S: AsRef<str> {
252        self.argv = Some(
253            argv.into_iter().skip(1).map(|s| s.as_ref().to_owned()).collect()
254        );
255        self
256    }
257
258    /// Enables the "options first" Docopt behavior.
259    ///
260    /// The options first behavior means that all flags *must* appear before
261    /// position arguments. That is, after the first position argument is
262    /// seen, all proceeding arguments are interpreted as positional
263    /// arguments unconditionally.
264    pub fn options_first(mut self, yes: bool) -> Docopt {
265        self.options_first = yes;
266        self
267    }
268
269    /// Enables automatic handling of `--help`.
270    ///
271    /// When this is enabled and `--help` appears anywhere in the arguments,
272    /// then a `Help` error will be returned. You may then use the `exit`
273    /// method on the error value to conveniently quit the program (which will
274    /// print the full usage string to stdout).
275    ///
276    /// Note that for this to work, `--help` must be a valid pattern.
277    ///
278    /// When disabled, there is no special handling of `--help`.
279    pub fn help(mut self, yes: bool) -> Docopt {
280        self.help = yes;
281        self
282    }
283
284    /// Enables automatic handling of `--version`.
285    ///
286    /// When this is enabled and `--version` appears anywhere in the arguments,
287    /// then a `Version(s)` error will be returned, where `s` is the string
288    /// given here. You may then use the `exit` method on the error value to
289    /// convenient quit the program (which will print the version to stdout).
290    ///
291    /// When disabled (a `None` value), there is no special handling of
292    /// `--version`.
293    pub fn version(mut self, version: Option<String>) -> Docopt {
294        self.version = version;
295        self
296    }
297
298    #[doc(hidden)]
299    pub fn parser(&self) -> &Parser {
300        &self.p
301    }
302
303    fn err_with_usage(&self, e: Error) -> Error {
304        WithProgramUsage(
305            Box::new(e), self.p.usage.trim().into())
306    }
307
308    fn err_with_full_doc(&self, e: Error) -> Error {
309        WithProgramUsage(
310            Box::new(e), self.p.full_doc.trim().into())
311    }
312
313    fn get_argv() -> Vec<String> {
314        // Hmm, we should probably handle a Unicode decode error here... ---AG
315        ::std::env::args().skip(1).collect()
316    }
317}
318
319/// A map containing matched values from command line arguments.
320///
321/// The keys are just as specified in Docopt: `--flag` for a long flag or
322/// `-f` for a short flag. (If `-f` is a synonym for `--flag`, then either
323/// key will work.) `ARG` or `<arg>` specify a positional argument and `cmd`
324/// specifies a command.
325#[derive(Clone)]
326pub struct ArgvMap {
327    #[doc(hidden)]
328    pub map: SynonymMap<String, Value>,
329}
330
331impl ArgvMap {
332    /// Tries to deserialize the map of values into a struct.
333    ///
334    /// This method should always be called to deserialize a `ArgvMap` into
335    /// a struct. All fields of the struct must map to a corresponding key
336    /// in the `ArgvMap`. To this end, each member must have a special prefix
337    /// corresponding to the different kinds of patterns in Docopt. There are
338    /// three prefixes: `flag_`, `arg_` and `cmd_` which respectively
339    /// correspond to short/long flags, positional arguments and commands.
340    ///
341    /// If a Docopt item has a `-` in its name, then it is converted to an `_`.
342    ///
343    /// # Example
344    ///
345    /// ```rust
346    /// # fn main() {
347    /// use serde::Deserialize;
348    ///
349    /// use docopt::Docopt;
350    ///
351    /// const USAGE: &'static str = "
352    /// Usage: cargo [options] (build | test)
353    ///        cargo --help
354    ///
355    /// Options: -v, --verbose
356    ///          -h, --help
357    /// ";
358    ///
359    /// #[derive(Deserialize)]
360    /// struct Args {
361    ///   cmd_build: bool,
362    ///   cmd_test: bool,
363    ///   flag_verbose: bool,
364    ///   flag_h: bool,
365    /// }
366    ///
367    /// let argv = || vec!["cargo", "build", "-v"].into_iter();
368    /// let args: Args = Docopt::new(USAGE)
369    ///     .and_then(|d| d.argv(argv()).deserialize())
370    ///     .unwrap_or_else(|e| e.exit());
371    /// assert!(args.cmd_build && !args.cmd_test
372    ///         && args.flag_verbose && !args.flag_h);
373    /// # }
374    /// ```
375    ///
376    /// Note that in the above example, `flag_h` is used but `flag_help`
377    /// could also be used. (In fact, both could be used at the same time.)
378    ///
379    /// In this example, only the `bool` type was used, but any type satisfying
380    /// the `Deserialize` trait is valid.
381    pub fn deserialize<'de, T: de::Deserialize<'de>>(self) -> Result<T> {
382        de::Deserialize::deserialize(&mut Deserializer {
383                                              vals: self,
384                                              stack: vec![],
385                                          })
386    }
387
388    /// Finds the value corresponding to `key` and calls `as_bool()` on it.
389    /// If the key does not exist, `false` is returned.
390    pub fn get_bool(&self, key: &str) -> bool {
391        self.find(key).map_or(false, |v| v.as_bool())
392    }
393
394    /// Finds the value corresponding to `key` and calls `as_count()` on it.
395    /// If the key does not exist, `0` is returned.
396    pub fn get_count(&self, key: &str) -> u64 {
397        self.find(key).map_or(0, |v| v.as_count())
398    }
399
400    /// Finds the value corresponding to `key` and calls `as_str()` on it.
401    /// If the key does not exist, `""` is returned.
402    pub fn get_str(&self, key: &str) -> &str {
403        self.find(key).map_or("", |v| v.as_str())
404    }
405
406    /// Finds the value corresponding to `key` and calls `as_vec()` on it.
407    /// If the key does not exist, `vec!()` is returned.
408    pub fn get_vec(&self, key: &str) -> Vec<&str> {
409        self.find(key).map(|v| v.as_vec()).unwrap_or(vec!())
410    }
411
412    /// Return the raw value corresponding to some `key`.
413    ///
414    /// `key` should be a string in the traditional Docopt format. e.g.,
415    /// `<arg>` or `--flag`.
416    pub fn find(&self, key: &str) -> Option<&Value> {
417        self.map.find(&key.into())
418    }
419
420    /// Return the number of values, not including synonyms.
421    pub fn len(&self) -> usize {
422        self.map.len()
423    }
424
425    /// Converts a Docopt key to a struct field name.
426    /// This makes a half-hearted attempt at making the key a valid struct
427    /// field name (like replacing `-` with `_`), but it does not otherwise
428    /// guarantee that the result is a valid struct field name.
429    #[doc(hidden)]
430    pub fn key_to_struct_field(name: &str) -> String {
431        lazy_static! {
432            static ref RE: Regex = regex!(
433                r"^(?:--?(?P<flag>\S+)|(?:(?P<argu>\p{Lu}+)|<(?P<argb>[^>]+)>)|(?P<cmd>\S+))$"
434            );
435        }
436        fn sanitize(name: &str) -> String {
437            name.replace("-", "_")
438        }
439
440        RE.replace(name, |cap: &Captures<'_>| {
441            let (flag, cmd) = (
442                cap_or_empty(cap, "flag"),
443                cap_or_empty(cap, "cmd"),
444            );
445            let (argu, argb) = (
446                cap_or_empty(cap, "argu"),
447                cap_or_empty(cap, "argb"),
448            );
449            let (prefix, name) =
450                if !flag.is_empty() {
451                    ("flag_", flag)
452                } else if !argu.is_empty() {
453                    ("arg_", argu)
454                } else if !argb.is_empty() {
455                    ("arg_", argb)
456                } else if !cmd.is_empty() {
457                    ("cmd_", cmd)
458                } else {
459                    panic!("Unknown ArgvMap key: '{}'", name)
460                };
461            let mut prefix = prefix.to_owned();
462            prefix.push_str(&sanitize(name));
463            prefix
464        }).into_owned()
465    }
466
467    /// Converts a struct field name to a Docopt key.
468    #[doc(hidden)]
469    pub fn struct_field_to_key(field: &str) -> String {
470        lazy_static! {
471            static ref FLAG: Regex = regex!(r"^flag_");
472            static ref ARG: Regex = regex!(r"^arg_");
473            static ref LETTERS: Regex = regex!(r"^\p{Lu}+$");
474            static ref CMD: Regex = regex!(r"^cmd_");
475        }
476        fn desanitize(name: &str) -> String {
477            name.replace("_", "-")
478        }
479        let name =
480            if field.starts_with("flag_") {
481                let name = FLAG.replace(field, "");
482                let mut pre_name = (if name.len() == 1 { "-" } else { "--" })
483                                   .to_owned();
484                pre_name.push_str(&*name);
485                pre_name
486            } else if field.starts_with("arg_") {
487                let name = ARG.replace(field, "").into_owned();
488                if LETTERS.is_match(&name) {
489                    name
490                } else {
491                    let mut pre_name = "<".to_owned();
492                    pre_name.push_str(&*name);
493                    pre_name.push('>');
494                    pre_name
495                }
496            } else if field.starts_with("cmd_") {
497                CMD.replace(field, "").into_owned()
498            } else {
499                panic!("Unrecognized struct field: '{}'", field)
500            };
501        desanitize(&*name)
502    }
503}
504
505impl fmt::Debug for ArgvMap {
506    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
507        if self.len() == 0 {
508            return write!(f, "{{EMPTY}}");
509        }
510
511        // This is a little crazy, but we want to group synonyms with
512        // their keys and sort them for predictable output.
513        let reverse: HashMap<&String, &String> =
514            self.map.synonyms().map(|(from, to)| (to, from)).collect();
515        let mut keys: Vec<&String> = self.map.keys().collect();
516        keys.sort();
517        let mut first = true;
518        for &k in &keys {
519            if !first { write!(f, "\n")?; } else { first = false; }
520            match reverse.get(&k) {
521                None => {
522                    write!(f, "{} => {:?}", k, self.map.get(k))?
523                }
524                Some(s) => {
525                    write!(f, "{}, {} => {:?}", s, k, self.map.get(k))?
526                }
527            }
528        }
529        Ok(())
530    }
531}
532
533/// A matched command line value.
534///
535/// The value can be a boolean, counted repetition, a plain string or a list
536/// of strings.
537///
538/// The various `as_{bool,count,str,vec}` methods provide convenient access
539/// to values without destructuring manually.
540#[derive(Clone, Debug, PartialEq)]
541pub enum Value {
542    /// A boolean value from a flag that has no argument.
543    ///
544    /// The presence of a flag means `true` and the absence of a flag
545    /// means `false`.
546    Switch(bool),
547
548    /// The number of occurrences of a repeated flag.
549    Counted(u64),
550
551    /// A positional or flag argument.
552    ///
553    /// This is `None` when the positional argument or flag is not present.
554    /// Note that it is possible to have `Some("")` for a present but empty
555    /// argument.
556    Plain(Option<String>),
557
558    /// A List of positional or flag arguments.
559    ///
560    /// This list may be empty when no arguments or flags are present.
561    List(Vec<String>),
562}
563
564impl Value {
565    /// Returns the value as a bool.
566    ///
567    /// Counted repetitions are `false` if `0` and `true` otherwise.
568    /// Plain strings are `true` if present and `false` otherwise.
569    /// Lists are `true` if non-empty and `false` otherwise.
570    pub fn as_bool(&self) -> bool {
571        match *self {
572            Switch(b) => b,
573            Counted(n) => n > 0,
574            Plain(None) => false,
575            Plain(Some(_)) => true,
576            List(ref vs) => !vs.is_empty(),
577        }
578    }
579
580    /// Returns the value as a count of the number of times it occurred.
581    ///
582    /// Booleans are `1` if `true` and `0` otherwise.
583    /// Plain strings are `1` if present and `0` otherwise.
584    /// Lists correspond to its length.
585    pub fn as_count(&self) -> u64 {
586        match *self {
587            Switch(b) => if b { 1 } else { 0 },
588            Counted(n) => n,
589            Plain(None) => 0,
590            Plain(Some(_)) => 1,
591            List(ref vs) => vs.len() as u64,
592        }
593    }
594
595    /// Returns the value as a string.
596    ///
597    /// All values return an empty string except for a non-empty plain string.
598    pub fn as_str(&self) -> &str {
599        match *self {
600            Switch(_) | Counted(_) | Plain(None) | List(_) => "",
601            Plain(Some(ref s)) => &**s,
602        }
603    }
604
605    /// Returns the value as a list of strings.
606    ///
607    /// Booleans, repetitions and empty strings correspond to an empty list.
608    /// Plain strings correspond to a list of length `1`.
609    pub fn as_vec(&self) -> Vec<&str> {
610        match *self {
611            Switch(_) | Counted(_) | Plain(None) => vec![],
612            Plain(Some(ref s)) => vec![&**s],
613            List(ref vs) => vs.iter().map(|s| &**s).collect(),
614        }
615    }
616}
617
618/// Deserializer for `ArgvMap` into your own `Deserialize`able types.
619///
620/// In general, you shouldn't have to use this type directly. It is exposed
621/// in case you want to write a generic function that produces a deserializable
622/// value. For example, here's a function that takes a usage string, an argv
623/// and produces a deserializable value:
624///
625/// ```rust
626/// # extern crate docopt;
627/// extern crate serde;
628/// # fn main() {
629/// use docopt::Docopt;
630/// use serde::de::Deserialize;
631///
632/// fn deserialize<'de, D: Deserialize<'de>>(usage: &str, argv: &[&str])
633///                         -> Result<D, docopt::Error> {
634///     Docopt::new(usage)
635///            .and_then(|d| d.argv(argv.iter()).deserialize())
636/// }
637/// # }
638pub struct Deserializer<'de> {
639    vals: ArgvMap,
640    stack: Vec<DeserializerItem<'de>>,
641}
642
643#[derive(Debug)]
644struct DeserializerItem<'de> {
645    key: String,
646    struct_field: &'de str,
647    val: Option<Value>,
648}
649
650macro_rules! derr(
651    ($($arg:tt)*) => (return Err(Deserialize(format!($($arg)*))))
652);
653
654impl<'de> Deserializer<'de> {
655    fn push(&mut self, struct_field: &'de str) {
656        let key = ArgvMap::struct_field_to_key(struct_field);
657        self.stack
658            .push(DeserializerItem {
659                      key: key.clone(),
660                      struct_field: struct_field,
661                      val: self.vals.find(&*key).cloned(),
662                  });
663    }
664
665    fn pop(&mut self) -> Result<DeserializerItem<'_>> {
666        match self.stack.pop() {
667            None => derr!("Could not deserialize value into unknown key."),
668            Some(it) => Ok(it),
669        }
670    }
671
672    fn pop_key_val(&mut self) -> Result<(String, Value)> {
673        let it = self.pop()?;
674        match it.val {
675            None => {
676                derr!("Could not find argument '{}' (from struct field '{}').
677Note that each struct field must have the right key prefix, which must
678be one of `cmd_`, `flag_` or `arg_`.",
679                      it.key,
680                      it.struct_field)
681            }
682            Some(v) => Ok((it.key, v)),
683        }
684    }
685
686    fn pop_val(&mut self) -> Result<Value> {
687        let (_, v) = self.pop_key_val()?;
688        Ok(v)
689    }
690
691    fn to_number<T>(&mut self, expect: &str) -> Result<T>
692        where T: FromStr + ToString,
693              <T as FromStr>::Err: Debug
694    {
695        let (k, v) = self.pop_key_val()?;
696        match v {
697            Counted(n) => Ok(n.to_string().parse().unwrap()), // lol
698            _ => {
699                if v.as_str().trim().is_empty() {
700                    Ok("0".parse().unwrap()) // lol
701                } else {
702                    match v.as_str().parse() {
703                        Err(_) => {
704                            derr!("Could not deserialize '{}' to {} for '{}'.",
705                                  v.as_str(),
706                                  expect,
707                                  k)
708                        }
709                        Ok(v) => Ok(v),
710                    }
711                }
712            }
713        }
714    }
715
716    fn to_float(&mut self, expect: &str) -> Result<f64> {
717        let (k, v) = self.pop_key_val()?;
718        match v {
719            Counted(n) => Ok(n as f64),
720            _ => {
721                match v.as_str().parse() {
722                    Err(_) => {
723                        derr!("Could not deserialize '{}' to {} for '{}'.",
724                              v.as_str(),
725                              expect,
726                              k)
727                    }
728                    Ok(v) => Ok(v),
729                }
730            }
731        }
732    }
733}
734
735macro_rules! deserialize_num {
736    ($name:ident, $method:ident, $ty:ty) => (
737        fn $name<V>(self, visitor: V) -> Result<V::Value>
738            where V: de::Visitor<'de>
739        {
740            visitor.$method(self.to_number::<$ty>(stringify!($ty)).map(|n| n as $ty)?)
741        }
742    );
743}
744
745impl<'a, 'de> ::serde::Deserializer<'de> for &'a mut Deserializer<'de> {
746    type Error = Error;
747
748    fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value>
749        where V: de::Visitor<'de>
750    {
751        unimplemented!()
752    }
753
754    fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
755        where V: de::Visitor<'de>
756    {
757        visitor.visit_bool(self.pop_val().map(|v| v.as_bool())?)
758    }
759
760    // wish for stable macro concat_idents!
761    deserialize_num!(deserialize_i8, visit_i8, i8);
762    deserialize_num!(deserialize_i16, visit_i16, i16);
763    deserialize_num!(deserialize_i32, visit_i32, i32);
764    deserialize_num!(deserialize_i64, visit_i64, i64);
765    deserialize_num!(deserialize_u8, visit_u8, u8);
766    deserialize_num!(deserialize_u16, visit_u16, u16);
767    deserialize_num!(deserialize_u32, visit_u32, u32);
768    deserialize_num!(deserialize_u64, visit_u64, u64);
769
770    fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
771        where V: de::Visitor<'de>
772    {
773        visitor.visit_f32(self.to_float("f32").map(|n| n as f32)?)
774    }
775
776    fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value>
777        where V: de::Visitor<'de>
778    {
779        visitor.visit_f64(self.to_float("f64")?)
780    }
781
782    fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
783        where V: de::Visitor<'de>
784    {
785        let (k, v) = self.pop_key_val()?;
786        let vstr = v.as_str();
787        match vstr.chars().count() {
788            1 => visitor.visit_char(vstr.chars().next().unwrap()),
789            _ => derr!("Could not deserialize '{}' into char for '{}'.", vstr, k),
790        }
791    }
792
793    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
794        where V: de::Visitor<'de>
795    {
796        let s = self.pop_val()?;
797        visitor.visit_str(s.as_str())
798    }
799
800    fn deserialize_string<V>(self, visitor:V) -> Result<V::Value>
801        where V: de::Visitor<'de>
802    {
803        self.deserialize_str(visitor)
804    }
805
806    fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value>
807        where V: de::Visitor<'de>
808    {
809        unimplemented!()
810    }
811
812    fn deserialize_byte_buf<V>(self, _visitor: V) -> Result<V::Value>
813        where V: de::Visitor<'de>
814    {
815        unimplemented!()
816    }
817
818    fn  deserialize_option<V>(self, visitor: V) -> Result<V::Value>
819        where V: de::Visitor<'de>
820    {
821        let is_some = match self.stack.last() {
822            None => derr!("Could not deserialize value into unknown key."),
823            Some(it) => it.val.as_ref().map_or(false, |v| v.as_bool()),
824        };
825        if is_some {
826            visitor.visit_some(self)
827        } else {
828            visitor.visit_none()
829        }
830    }
831
832    fn deserialize_unit<V>(self, _visitor: V) -> Result<V::Value>
833        where V: de::Visitor<'de>
834    {
835        // I don't know what the right thing is here, so just fail for now.
836        panic!("I don't know how to read into a nil value.")
837    }
838
839    fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
840        where V: de::Visitor<'de>
841    {
842        visitor.visit_unit()
843    }
844
845    fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
846        where V: de::Visitor<'de>
847    {
848        visitor.visit_newtype_struct(self)
849    }
850
851    fn deserialize_tuple<V>(self, _len: usize, _visitor: V) -> Result<V::Value>
852        where V: de::Visitor<'de>
853    {
854        unimplemented!()
855    }
856
857    fn deserialize_tuple_struct<V>(self,
858                                   _name: &'static str,
859                                   _len: usize,
860                                   _visitor: V)
861                                   -> Result<V::Value>
862        where V: de::Visitor<'de>
863    {
864        unimplemented!()
865    }
866
867    fn deserialize_map<V>(self, _visitor: V) -> Result<V::Value>
868        where V: de::Visitor<'de>
869    {
870        unimplemented!()
871    }
872
873    fn deserialize_seq<V>(mut self, visitor: V) -> Result<V::Value>
874        where V: de::Visitor<'de>
875    {
876        let (key, struct_field, val) = match self.stack.pop() {
877            None => derr!("Could not deserialize value into unknown key."),
878            Some(DeserializerItem {key, struct_field, val}) => (key, struct_field, val),
879        };
880        let list = val.unwrap_or(List(vec![]));
881        let vals = list.as_vec();
882        for val in vals.iter().rev() {
883            self.stack
884                .push(DeserializerItem {
885                          key: key.clone(),
886                          struct_field: struct_field,
887                          val: Some(Plain(Some((*val).into()))),
888                      });
889        }
890        visitor.visit_seq(SeqDeserializer::new(&mut self, vals.len()))
891    }
892
893    fn deserialize_struct<V>(mut self,
894                             _: &str,
895                             fields: &'static [&'static str],
896                             visitor: V)
897                             -> Result<V::Value>
898        where V: de::Visitor<'de>
899    {
900        visitor.visit_seq(StructDeserializer::new(&mut self, fields))
901    }
902
903    fn deserialize_enum<V>(self, _name: &str, variants: &[&str], visitor: V) -> Result<V::Value>
904        where V: de::Visitor<'de>
905    {
906        let v = self.pop_val()?.as_str().to_lowercase();
907        let s = match variants.iter().find(|&n| n.to_lowercase() == v) {
908            Some(s) => s,
909            None => {
910                derr!("Could not match '{}' with any of \
911                           the allowed variants: {:?}",
912                      v,
913                      variants)
914            }
915        };
916        visitor.visit_enum(s.into_deserializer())
917    }
918
919    fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
920        where V: de::Visitor<'de>
921    {
922        self.deserialize_str(visitor)
923    }
924
925    fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
926        where V: de::Visitor<'de>
927    {
928        self.deserialize_any(visitor)
929    }
930}
931
932struct SeqDeserializer<'a, 'de: 'a> {
933    de: &'a mut Deserializer<'de>,
934    len: usize,
935}
936
937impl<'a, 'de> SeqDeserializer<'a, 'de> {
938    fn new(de: &'a mut Deserializer<'de>, len: usize) -> Self {
939        SeqDeserializer { de: de, len: len }
940    }
941}
942
943impl<'a, 'de> de::SeqAccess<'de> for SeqDeserializer<'a, 'de> {
944    type Error = Error;
945
946    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
947        where T: de::DeserializeSeed<'de>
948    {
949        if self.len == 0 {
950            return Ok(None);
951        }
952        self.len -= 1;
953        seed.deserialize(&mut *self.de).map(Some)
954    }
955
956    fn size_hint(&self) -> Option<usize> {
957        return Some(self.len);
958    }
959}
960
961struct StructDeserializer<'a, 'de: 'a> {
962    de: &'a mut Deserializer<'de>,
963    fields: &'static [&'static str],
964}
965
966impl<'a, 'de> StructDeserializer<'a, 'de> {
967    fn new(de: &'a mut Deserializer<'de>, fields: &'static [&'static str]) -> Self {
968        StructDeserializer {
969            de: de,
970            fields: fields,
971        }
972    }
973}
974
975impl<'a, 'de> de::SeqAccess<'de> for StructDeserializer<'a, 'de> {
976    type Error = Error;
977
978    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
979        where T: de::DeserializeSeed<'de>
980    {
981        if self.fields.len() == 0 {
982            return Ok(None);
983        }
984        self.de.push(self.fields[0]);
985        self.fields = &self.fields[1..];
986        seed.deserialize(&mut *self.de).map(Some)
987    }
988
989    fn size_hint(&self) -> Option<usize> {
990        return Some(self.fields.len());
991    }
992}