1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
use std::collections::HashMap; use args::SubCommand; use args::flagarg::FlagArg; use args::optarg::OptArg; use args::posarg::PosArg; /// Used to get information about the arguments that /// where supplied to the program at runtime. /// /// /// Fields of `ArgMatches` aren't designed to be used directly, only /// the methods in order to query information. /// /// # Example /// /// ```no_run /// # use clap::{App, Arg}; /// let matches = App::new("MyApp") /// // adding of arguments and configuration goes here... /// # .arg(Arg::new("config") /// # .long("config") /// # .required(true) /// # .takes_value(true)) /// # .arg(Arg::new("debug") /// # .short("d") /// # .multiple(true)) /// .get_matches(); /// // if you had an argument named "output" that takes a value /// if let Some(o) = matches.value_of("output") { /// println!("Value for output: {}", o); /// } /// /// // Although not advised, if you have a required argument /// // you can call .unwrap() because the program will exit long before /// // here at noticing the user didn't supply a required argument... /// // use at your own risk ;) /// println!("Config file: {}", matches.value_of("config").unwrap()); /// /// // You can check the present of an argument /// if matches.is_present("debug") { /// // Checking if "debug" was present was necessary, /// // as occurrences returns 0 if a flag isn't found /// // but we can check how many times "debug" was found /// // if we allow multiple (if multiple isn't allowed it always be 1 or 0) /// if matches.occurrences_of("debug") > 1 { /// println!("Debug mode is REALLY on"); /// } else { /// println!("Debug mode kind of on"); /// } /// } /// /// // You can get the sub-matches of a particular subcommand (in this case "test") /// // If "test" had it's own "-l" flag you could check for it's presence accordingly /// if let Some(ref matches) = matches.subcommand_matches("test") { /// if matches.is_present("list") { /// println!("Printing testing lists..."); /// } else { /// println!("Not printing testing lists..."); /// } /// } pub struct ArgMatches<'a> { // pub matches_of: &'static str, pub flags: HashMap<&'a str, FlagArg>, pub opts: HashMap<&'a str, OptArg>, pub positionals: HashMap<&'a str, PosArg>, pub subcommand: Option<Box<SubCommand<'a>>> } impl<'a> ArgMatches<'a> { /// Creates a new instance of `ArgMatches`. This ins't called directly, but /// through the `.get_matches()` method of `App` /// /// # Example /// /// ```no_run /// # use clap::{App, Arg}; /// let matches = App::new("myprog").get_matches(); /// ``` pub fn new() -> ArgMatches<'a> { ArgMatches { // matches_of: name, flags: HashMap::new(), opts: HashMap::new(), positionals: HashMap::new(), subcommand: None } } /// Gets the value of a specific option or positional argument (i.e. an argument that takes /// an additional value at runtime). If the option wasn't present at runtime /// it returns `None`. /// /// *NOTE:* If getting a value for an option or positional argument that allows multiples, /// prefer `values_of()` as `value_of()` will only return the _*first*_ value. /// /// # Example /// /// ```no_run /// # use clap::{App, Arg}; /// # let matches = App::new("myapp").arg(Arg::new("output").takes_value(true)).get_matches(); /// if let Some(o) = matches.value_of("output") { /// println!("Value for output: {}", o); /// } /// ``` pub fn value_of<'n>(&self, name: &'n str) -> Option<&str> { if let Some(ref opt) = self.opts.get(name) { if let Some(ref s) = opt.values.iter().nth(0) { return Some(&s[..]); } } if let Some(ref pos) = self.positionals.get(name) { if let Some(ref s) = pos.values.iter().nth(0) { return Some(&s[..]); } } None } /// Gets the values of a specific option or positional argument in a vector (i.e. an argument /// that takes an additional value at runtime). If the option wasn't present at runtime it /// returns `None` /// /// # Example /// /// ```no_run /// # use clap::{App, Arg}; /// # let matches = App::new("myapp").arg(Arg::new("output").takes_value(true)).get_matches(); /// // If the program had option "-c" that took a value and was run /// // via "myapp -o some -o other -o file" /// // values_of() would return a [&str; 3] ("some", "other", "file") /// if let Some(os) = matches.values_of("output") { /// for o in os { /// println!("A value for output: {}", o); /// } /// } /// ``` pub fn values_of<'n>(&self, name: &'n str) -> Option<Vec<&str>> { if let Some(ref opt) = self.opts.get(name) { if opt.values.is_empty() { return None; } return Some(opt.values.iter().map(|s| &s[..]).collect::<Vec<_>>()); } if let Some(ref pos) = self.positionals.get(name) { if pos.values.is_empty() { return None; } return Some(pos.values.iter().map(|s| &s[..]).collect::<Vec<_>>()); } None } /// Checks if a flag was argument was supplied at runtime. **DOES NOT** work for /// option or positional arguments (use `.value_of()` instead) /// /// /// # Example /// /// ```no_run /// # use clap::{App, Arg}; /// # let matches = App::new("myapp").arg(Arg::new("output").takes_value(true)).get_matches(); /// if matches.is_present("output") { /// println!("The output argument was used!"); /// } /// ``` pub fn is_present<'n>(&self, name: &'n str) -> bool { if let Some(ref sc) = self.subcommand { if sc.name == name { return true; } } if self.flags.contains_key(name) {return true;} if self.opts.contains_key(name) {return true;} if self.positionals.contains_key(name) {return true;} false } /// Checks the number of occurrences of an option, flag, or positional argument at runtime. /// If an option or flag isn't present it will return `0`, if the option or flag doesn't /// allow multiple occurrences, it will return `1` no matter how many times it occurred /// (unless it wasn't prsent) at all. /// /// /// # Example /// /// ```no_run /// # use clap::{App, Arg}; /// # let matches = App::new("myapp").arg(Arg::new("output").takes_value(true)).get_matches(); /// if matches.occurrences_of("debug") > 1 { /// println!("Debug mode is REALLY on"); /// } else { /// println!("Debug mode kind of on"); /// } /// ``` pub fn occurrences_of<'n>(&self, name: &'n str) -> u8 { if let Some(ref f) = self.flags.get(name) { return f.occurrences; } if let Some(ref o) = self.opts.get(name) { return o.occurrences; } if let Some(ref p) = self.positionals.get(name) { return p.occurrences; } 0 } /// If a subcommand was found, returns the ArgMatches struct associated with it's matches /// /// /// # Example /// /// ```no_run /// # use clap::{App, Arg, SubCommand}; /// # let app_matches = App::new("myapp").subcommand(SubCommand::new("test")).get_matches(); /// if let Some(matches) = app_matches.subcommand_matches("test") { /// // Use matches as normal /// } /// ``` pub fn subcommand_matches<'n>(&self, name: &'n str) -> Option<&ArgMatches> { if let Some( ref sc) = self.subcommand { if sc.name != name { return None; } return Some(&sc.matches); } None } /// If a subcommand was found, returns the name associated with it /// /// /// # Example /// /// ```no_run /// # use clap::{App, Arg, SubCommand}; /// # let app_matches = App::new("myapp").subcommand(SubCommand::new("test")).get_matches(); /// match app_matches.subcommand_name() { /// Some("test") => {}, // test was used /// Some("config") => {}, // config was used /// _ => {}, // Either no subcommand or one not tested for... /// } /// ``` pub fn subcommand_name(&self) -> Option<&str> { if let Some( ref sc ) = self.subcommand { return Some(&sc.name[..]); } None } }