1 use std::collections::HashMap;
2 use std::error::Error as StdError;
3 use std::fmt::{self, Debug};
4 use std::io::{self, Write};
5 use std::str::FromStr;
6 use std::result;
7 
8 use lazy_static::lazy_static;
9 use regex::{Captures, Regex};
10 use serde::de;
11 use serde::de::IntoDeserializer;
12 
13 use crate::parse::Parser;
14 use crate::synonym::SynonymMap;
15 
16 use self::Value::{Switch, Counted, Plain, List};
17 use self::Error::{Usage, Argv, NoMatch, Deserialize, WithProgramUsage, Help, Version};
18 
19 use 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)]
48 pub 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 
91 impl 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.
fatal(&self) -> bool97     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`.
exit(&self) -> !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 
122 type Result<T> = result::Result<T, Error>;
123 
124 impl fmt::Display for Error {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result125     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 
145 impl StdError for Error {
source(&self) -> Option<&(dyn StdError + 'static)>146     fn source(&self) -> Option<&(dyn StdError + 'static)> {
147         match *self {
148             WithProgramUsage(ref cause, _) => Some(&**cause),
149             _ => None,
150         }
151     }
152 }
153 
154 impl de::Error for Error {
custom<T: fmt::Display>(msg: T) -> Self155     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)]
164 pub struct Docopt {
165     p: Parser,
166     argv: Option<Vec<String>>,
167     options_first: bool,
168     help: bool,
169     version: Option<String>,
170 }
171 
172 impl 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.
new<S>(usage: S) -> Result<Docopt> where S: ::std::ops::Deref<Target=str>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`.
deserialize<'a, 'de: 'a, D>(&'a self) -> Result<D> where D: de::Deserialize<'de>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.
parse(&self) -> Result<ArgvMap>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.
argv<I, S>(mut self, argv: I) -> Docopt where I: IntoIterator<Item=S>, S: AsRef<str>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.
options_first(mut self, yes: bool) -> Docopt264     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`.
help(mut self, yes: bool) -> Docopt279     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`.
version(mut self, version: Option<String>) -> Docopt293     pub fn version(mut self, version: Option<String>) -> Docopt {
294         self.version = version;
295         self
296     }
297 
298     #[doc(hidden)]
parser(&self) -> &Parser299     pub fn parser(&self) -> &Parser {
300         &self.p
301     }
302 
err_with_usage(&self, e: Error) -> Error303     fn err_with_usage(&self, e: Error) -> Error {
304         WithProgramUsage(
305             Box::new(e), self.p.usage.trim().into())
306     }
307 
err_with_full_doc(&self, e: Error) -> Error308     fn err_with_full_doc(&self, e: Error) -> Error {
309         WithProgramUsage(
310             Box::new(e), self.p.full_doc.trim().into())
311     }
312 
get_argv() -> Vec<String>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)]
326 pub struct ArgvMap {
327     #[doc(hidden)]
328     pub map: SynonymMap<String, Value>,
329 }
330 
331 impl 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.
deserialize<'de, T: de::Deserialize<'de>>(self) -> Result<T>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.
get_bool(&self, key: &str) -> bool390     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.
get_count(&self, key: &str) -> u64396     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.
get_str(&self, key: &str) -> &str402     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.
get_vec(&self, key: &str) -> Vec<&str>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`.
find(&self, key: &str) -> Option<&Value>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.
len(&self) -> usize421     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)]
key_to_struct_field(name: &str) -> String430     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)]
struct_field_to_key(field: &str) -> String469     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 
505 impl fmt::Debug for ArgvMap {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result506     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)]
541 pub 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 
564 impl 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.
as_bool(&self) -> bool570     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.
as_count(&self) -> u64585     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.
as_str(&self) -> &str598     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`.
as_vec(&self) -> Vec<&str>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 /// # }
638 pub struct Deserializer<'de> {
639     vals: ArgvMap,
640     stack: Vec<DeserializerItem<'de>>,
641 }
642 
643 #[derive(Debug)]
644 struct DeserializerItem<'de> {
645     key: String,
646     struct_field: &'de str,
647     val: Option<Value>,
648 }
649 
650 macro_rules! derr(
651     ($($arg:tt)*) => (return Err(Deserialize(format!($($arg)*))))
652 );
653 
654 impl<'de> Deserializer<'de> {
push(&mut self, struct_field: &'de str)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 
pop(&mut self) -> Result<DeserializerItem<'_>>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 
pop_key_val(&mut self) -> Result<(String, Value)>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 '{}').
677 Note that each struct field must have the right key prefix, which must
678 be one of `cmd_`, `flag_` or `arg_`.",
679                       it.key,
680                       it.struct_field)
681             }
682             Some(v) => Ok((it.key, v)),
683         }
684     }
685 
pop_val(&mut self) -> Result<Value>686     fn pop_val(&mut self) -> Result<Value> {
687         let (_, v) = self.pop_key_val()?;
688         Ok(v)
689     }
690 
to_number<T>(&mut self, expect: &str) -> Result<T> where T: FromStr + ToString, <T as FromStr>::Err: Debug691     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 
to_float(&mut self, expect: &str) -> Result<f64>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 
735 macro_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 
745 impl<'a, 'de> ::serde::Deserializer<'de> for &'a mut Deserializer<'de> {
746     type Error = Error;
747 
deserialize_any<V>(self, _visitor: V) -> Result<V::Value> where V: de::Visitor<'de>748     fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value>
749         where V: de::Visitor<'de>
750     {
751         unimplemented!()
752     }
753 
deserialize_bool<V>(self, visitor: V) -> Result<V::Value> where V: de::Visitor<'de>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 
deserialize_f32<V>(self, visitor: V) -> Result<V::Value> where V: de::Visitor<'de>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 
deserialize_f64<V>(self, visitor: V) -> Result<V::Value> where V: de::Visitor<'de>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 
deserialize_char<V>(self, visitor: V) -> Result<V::Value> where V: de::Visitor<'de>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 
deserialize_str<V>(self, visitor: V) -> Result<V::Value> where V: de::Visitor<'de>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 
deserialize_string<V>(self, visitor:V) -> Result<V::Value> where V: de::Visitor<'de>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 
deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value> where V: de::Visitor<'de>806     fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value>
807         where V: de::Visitor<'de>
808     {
809         unimplemented!()
810     }
811 
deserialize_byte_buf<V>(self, _visitor: V) -> Result<V::Value> where V: de::Visitor<'de>812     fn deserialize_byte_buf<V>(self, _visitor: V) -> Result<V::Value>
813         where V: de::Visitor<'de>
814     {
815         unimplemented!()
816     }
817 
deserialize_option<V>(self, visitor: V) -> Result<V::Value> where V: de::Visitor<'de>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 
deserialize_unit<V>(self, _visitor: V) -> Result<V::Value> where V: de::Visitor<'de>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 
deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value> where V: de::Visitor<'de>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 
deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value> where V: de::Visitor<'de>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 
deserialize_tuple<V>(self, _len: usize, _visitor: V) -> Result<V::Value> where V: de::Visitor<'de>851     fn deserialize_tuple<V>(self, _len: usize, _visitor: V) -> Result<V::Value>
852         where V: de::Visitor<'de>
853     {
854         unimplemented!()
855     }
856 
deserialize_tuple_struct<V>(self, _name: &'static str, _len: usize, _visitor: V) -> Result<V::Value> where V: de::Visitor<'de>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 
deserialize_map<V>(self, _visitor: V) -> Result<V::Value> where V: de::Visitor<'de>867     fn deserialize_map<V>(self, _visitor: V) -> Result<V::Value>
868         where V: de::Visitor<'de>
869     {
870         unimplemented!()
871     }
872 
deserialize_seq<V>(mut self, visitor: V) -> Result<V::Value> where V: de::Visitor<'de>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 
deserialize_struct<V>(mut self, _: &str, fields: &'static [&'static str], visitor: V) -> Result<V::Value> where V: de::Visitor<'de>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 
deserialize_enum<V>(self, _name: &str, variants: &[&str], visitor: V) -> Result<V::Value> where V: de::Visitor<'de>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 
deserialize_identifier<V>(self, visitor: V) -> Result<V::Value> where V: de::Visitor<'de>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 
deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value> where V: de::Visitor<'de>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 
932 struct SeqDeserializer<'a, 'de: 'a> {
933     de: &'a mut Deserializer<'de>,
934     len: usize,
935 }
936 
937 impl<'a, 'de> SeqDeserializer<'a, 'de> {
new(de: &'a mut Deserializer<'de>, len: usize) -> Self938     fn new(de: &'a mut Deserializer<'de>, len: usize) -> Self {
939         SeqDeserializer { de: de, len: len }
940     }
941 }
942 
943 impl<'a, 'de> de::SeqAccess<'de> for SeqDeserializer<'a, 'de> {
944     type Error = Error;
945 
next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>> where T: de::DeserializeSeed<'de>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 
size_hint(&self) -> Option<usize>956     fn size_hint(&self) -> Option<usize> {
957         return Some(self.len);
958     }
959 }
960 
961 struct StructDeserializer<'a, 'de: 'a> {
962     de: &'a mut Deserializer<'de>,
963     fields: &'static [&'static str],
964 }
965 
966 impl<'a, 'de> StructDeserializer<'a, 'de> {
new(de: &'a mut Deserializer<'de>, fields: &'static [&'static str]) -> Self967     fn new(de: &'a mut Deserializer<'de>, fields: &'static [&'static str]) -> Self {
968         StructDeserializer {
969             de: de,
970             fields: fields,
971         }
972     }
973 }
974 
975 impl<'a, 'de> de::SeqAccess<'de> for StructDeserializer<'a, 'de> {
976     type Error = Error;
977 
next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>> where T: de::DeserializeSeed<'de>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 
size_hint(&self) -> Option<usize>989     fn size_hint(&self) -> Option<usize> {
990         return Some(self.fields.len());
991     }
992 }
993