1 #[cfg(debug_assertions)] 2 use crate::util::AnyValueId; 3 4 /// Behavior of arguments when they are encountered while parsing 5 /// 6 /// # Examples 7 /// 8 /// ```rust 9 /// # #[cfg(feature = "help")] { 10 /// # use clap_builder as clap; 11 /// # use clap::Command; 12 /// # use clap::Arg; 13 /// let cmd = Command::new("mycmd") 14 /// .arg( 15 /// Arg::new("special-help") 16 /// .short('?') 17 /// .action(clap::ArgAction::Help) 18 /// ); 19 /// 20 /// // Existing help still exists 21 /// let err = cmd.clone().try_get_matches_from(["mycmd", "-h"]).unwrap_err(); 22 /// assert_eq!(err.kind(), clap::error::ErrorKind::DisplayHelp); 23 /// 24 /// // New help available 25 /// let err = cmd.try_get_matches_from(["mycmd", "-?"]).unwrap_err(); 26 /// assert_eq!(err.kind(), clap::error::ErrorKind::DisplayHelp); 27 /// # } 28 /// ``` 29 #[derive(Clone, Debug)] 30 #[non_exhaustive] 31 #[allow(missing_copy_implementations)] // In the future, we may accept `Box<dyn ...>` 32 pub enum ArgAction { 33 /// When encountered, store the associated value(s) in [`ArgMatches`][crate::ArgMatches] 34 /// 35 /// **NOTE:** If the argument has previously been seen, it will result in a 36 /// [`ArgumentConflict`][crate::error::ErrorKind::ArgumentConflict] unless 37 /// [`Command::args_override_self(true)`][crate::Command::args_override_self] is set. 38 /// 39 /// # Examples 40 /// 41 /// ```rust 42 /// # use clap_builder as clap; 43 /// # use clap::Command; 44 /// # use clap::Arg; 45 /// let cmd = Command::new("mycmd") 46 /// .arg( 47 /// Arg::new("flag") 48 /// .long("flag") 49 /// .action(clap::ArgAction::Set) 50 /// ); 51 /// 52 /// let matches = cmd.try_get_matches_from(["mycmd", "--flag", "value"]).unwrap(); 53 /// assert!(matches.contains_id("flag")); 54 /// assert_eq!( 55 /// matches.get_many::<String>("flag").unwrap_or_default().map(|v| v.as_str()).collect::<Vec<_>>(), 56 /// vec!["value"] 57 /// ); 58 /// ``` 59 Set, 60 /// When encountered, store the associated value(s) in [`ArgMatches`][crate::ArgMatches] 61 /// 62 /// # Examples 63 /// 64 /// ```rust 65 /// # use clap_builder as clap; 66 /// # use clap::Command; 67 /// # use clap::Arg; 68 /// let cmd = Command::new("mycmd") 69 /// .arg( 70 /// Arg::new("flag") 71 /// .long("flag") 72 /// .action(clap::ArgAction::Append) 73 /// ); 74 /// 75 /// let matches = cmd.try_get_matches_from(["mycmd", "--flag", "value1", "--flag", "value2"]).unwrap(); 76 /// assert!(matches.contains_id("flag")); 77 /// assert_eq!( 78 /// matches.get_many::<String>("flag").unwrap_or_default().map(|v| v.as_str()).collect::<Vec<_>>(), 79 /// vec!["value1", "value2"] 80 /// ); 81 /// ``` 82 Append, 83 /// When encountered, act as if `"true"` was encountered on the command-line 84 /// 85 /// If no [`default_value`][super::Arg::default_value] is set, it will be `false`. 86 /// 87 /// No value is allowed. To optionally accept a value, see 88 /// [`Arg::default_missing_value`][super::Arg::default_missing_value] 89 /// 90 /// **NOTE:** If the argument has previously been seen, it will result in a 91 /// [`ArgumentConflict`][crate::error::ErrorKind::ArgumentConflict] unless 92 /// [`Command::args_override_self(true)`][crate::Command::args_override_self] is set. 93 /// 94 /// # Examples 95 /// 96 /// ```rust 97 /// # use clap_builder as clap; 98 /// # use clap::Command; 99 /// # use clap::Arg; 100 /// let cmd = Command::new("mycmd") 101 /// .arg( 102 /// Arg::new("flag") 103 /// .long("flag") 104 /// .action(clap::ArgAction::SetTrue) 105 /// ); 106 /// 107 /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag"]).unwrap(); 108 /// assert!(matches.contains_id("flag")); 109 /// assert_eq!( 110 /// matches.get_flag("flag"), 111 /// true 112 /// ); 113 /// 114 /// let matches = cmd.try_get_matches_from(["mycmd"]).unwrap(); 115 /// assert!(matches.contains_id("flag")); 116 /// assert_eq!( 117 /// matches.get_flag("flag"), 118 /// false 119 /// ); 120 /// ``` 121 /// 122 /// You can use [`TypedValueParser::map`][crate::builder::TypedValueParser::map] to have the 123 /// flag control an application-specific type: 124 /// ```rust 125 /// # use clap_builder as clap; 126 /// # use clap::Command; 127 /// # use clap::Arg; 128 /// # use clap::builder::TypedValueParser as _; 129 /// # use clap::builder::BoolishValueParser; 130 /// let cmd = Command::new("mycmd") 131 /// .arg( 132 /// Arg::new("flag") 133 /// .long("flag") 134 /// .action(clap::ArgAction::SetTrue) 135 /// .value_parser( 136 /// BoolishValueParser::new() 137 /// .map(|b| -> usize { 138 /// if b { 10 } else { 5 } 139 /// }) 140 /// ) 141 /// ); 142 /// 143 /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag"]).unwrap(); 144 /// assert!(matches.contains_id("flag")); 145 /// assert_eq!( 146 /// matches.get_one::<usize>("flag").copied(), 147 /// Some(10) 148 /// ); 149 /// 150 /// let matches = cmd.try_get_matches_from(["mycmd"]).unwrap(); 151 /// assert!(matches.contains_id("flag")); 152 /// assert_eq!( 153 /// matches.get_one::<usize>("flag").copied(), 154 /// Some(5) 155 /// ); 156 /// ``` 157 SetTrue, 158 /// When encountered, act as if `"false"` was encountered on the command-line 159 /// 160 /// If no [`default_value`][super::Arg::default_value] is set, it will be `true`. 161 /// 162 /// No value is allowed. To optionally accept a value, see 163 /// [`Arg::default_missing_value`][super::Arg::default_missing_value] 164 /// 165 /// **NOTE:** If the argument has previously been seen, it will result in a 166 /// [`ArgumentConflict`][crate::error::ErrorKind::ArgumentConflict] unless 167 /// [`Command::args_override_self(true)`][crate::Command::args_override_self] is set. 168 /// 169 /// # Examples 170 /// 171 /// ```rust 172 /// # use clap_builder as clap; 173 /// # use clap::Command; 174 /// # use clap::Arg; 175 /// let cmd = Command::new("mycmd") 176 /// .arg( 177 /// Arg::new("flag") 178 /// .long("flag") 179 /// .action(clap::ArgAction::SetFalse) 180 /// ); 181 /// 182 /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag"]).unwrap(); 183 /// assert!(matches.contains_id("flag")); 184 /// assert_eq!( 185 /// matches.get_flag("flag"), 186 /// false 187 /// ); 188 /// 189 /// let matches = cmd.try_get_matches_from(["mycmd"]).unwrap(); 190 /// assert!(matches.contains_id("flag")); 191 /// assert_eq!( 192 /// matches.get_flag("flag"), 193 /// true 194 /// ); 195 /// ``` 196 SetFalse, 197 /// When encountered, increment a `u8` counter 198 /// 199 /// If no [`default_value`][super::Arg::default_value] is set, it will be `0`. 200 /// 201 /// No value is allowed. To optionally accept a value, see 202 /// [`Arg::default_missing_value`][super::Arg::default_missing_value] 203 /// 204 /// # Examples 205 /// 206 /// ```rust 207 /// # use clap_builder as clap; 208 /// # use clap::Command; 209 /// # use clap::Arg; 210 /// let cmd = Command::new("mycmd") 211 /// .arg( 212 /// Arg::new("flag") 213 /// .long("flag") 214 /// .action(clap::ArgAction::Count) 215 /// ); 216 /// 217 /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag", "--flag"]).unwrap(); 218 /// assert!(matches.contains_id("flag")); 219 /// assert_eq!( 220 /// matches.get_count("flag"), 221 /// 2 222 /// ); 223 /// 224 /// let matches = cmd.try_get_matches_from(["mycmd"]).unwrap(); 225 /// assert!(matches.contains_id("flag")); 226 /// assert_eq!( 227 /// matches.get_count("flag"), 228 /// 0 229 /// ); 230 /// ``` 231 Count, 232 /// When encountered, display [`Command::print_help`][super::Command::print_help] 233 /// 234 /// Depending on the flag, [`Command::print_long_help`][super::Command::print_long_help] may be shown 235 /// 236 /// # Examples 237 /// 238 /// ```rust 239 /// # #[cfg(feature = "help")] { 240 /// # use clap_builder as clap; 241 /// # use clap::Command; 242 /// # use clap::Arg; 243 /// let cmd = Command::new("mycmd") 244 /// .arg( 245 /// Arg::new("special-help") 246 /// .short('?') 247 /// .action(clap::ArgAction::Help) 248 /// ); 249 /// 250 /// // Existing help still exists 251 /// let err = cmd.clone().try_get_matches_from(["mycmd", "-h"]).unwrap_err(); 252 /// assert_eq!(err.kind(), clap::error::ErrorKind::DisplayHelp); 253 /// 254 /// // New help available 255 /// let err = cmd.try_get_matches_from(["mycmd", "-?"]).unwrap_err(); 256 /// assert_eq!(err.kind(), clap::error::ErrorKind::DisplayHelp); 257 /// # } 258 /// ``` 259 Help, 260 /// When encountered, display [`Command::print_help`][super::Command::print_help] 261 /// 262 /// # Examples 263 /// 264 /// ```rust 265 /// # #[cfg(feature = "help")] { 266 /// # use clap_builder as clap; 267 /// # use clap::Command; 268 /// # use clap::Arg; 269 /// let cmd = Command::new("mycmd") 270 /// .arg( 271 /// Arg::new("special-help") 272 /// .short('?') 273 /// .action(clap::ArgAction::HelpShort) 274 /// ); 275 /// 276 /// // Existing help still exists 277 /// let err = cmd.clone().try_get_matches_from(["mycmd", "-h"]).unwrap_err(); 278 /// assert_eq!(err.kind(), clap::error::ErrorKind::DisplayHelp); 279 /// 280 /// // New help available 281 /// let err = cmd.try_get_matches_from(["mycmd", "-?"]).unwrap_err(); 282 /// assert_eq!(err.kind(), clap::error::ErrorKind::DisplayHelp); 283 /// # } 284 /// ``` 285 HelpShort, 286 /// When encountered, display [`Command::print_long_help`][super::Command::print_long_help] 287 /// 288 /// # Examples 289 /// 290 /// ```rust 291 /// # #[cfg(feature = "help")] { 292 /// # use clap_builder as clap; 293 /// # use clap::Command; 294 /// # use clap::Arg; 295 /// let cmd = Command::new("mycmd") 296 /// .arg( 297 /// Arg::new("special-help") 298 /// .short('?') 299 /// .action(clap::ArgAction::HelpLong) 300 /// ); 301 /// 302 /// // Existing help still exists 303 /// let err = cmd.clone().try_get_matches_from(["mycmd", "-h"]).unwrap_err(); 304 /// assert_eq!(err.kind(), clap::error::ErrorKind::DisplayHelp); 305 /// 306 /// // New help available 307 /// let err = cmd.try_get_matches_from(["mycmd", "-?"]).unwrap_err(); 308 /// assert_eq!(err.kind(), clap::error::ErrorKind::DisplayHelp); 309 /// # } 310 /// ``` 311 HelpLong, 312 /// When encountered, display [`Command::version`][super::Command::version] 313 /// 314 /// Depending on the flag, [`Command::long_version`][super::Command::long_version] may be shown 315 /// 316 /// # Examples 317 /// 318 /// ```rust 319 /// # use clap_builder as clap; 320 /// # use clap::Command; 321 /// # use clap::Arg; 322 /// let cmd = Command::new("mycmd") 323 /// .version("1.0.0") 324 /// .arg( 325 /// Arg::new("special-version") 326 /// .long("special-version") 327 /// .action(clap::ArgAction::Version) 328 /// ); 329 /// 330 /// // Existing help still exists 331 /// let err = cmd.clone().try_get_matches_from(["mycmd", "--version"]).unwrap_err(); 332 /// assert_eq!(err.kind(), clap::error::ErrorKind::DisplayVersion); 333 /// 334 /// // New help available 335 /// let err = cmd.try_get_matches_from(["mycmd", "--special-version"]).unwrap_err(); 336 /// assert_eq!(err.kind(), clap::error::ErrorKind::DisplayVersion); 337 /// ``` 338 Version, 339 } 340 341 impl ArgAction { 342 /// Returns whether this action accepts values on the command-line 343 /// 344 /// [`default_values`][super::Arg::default_values] and [`env`][super::Arg::env] may still be 345 /// processed. takes_values(&self) -> bool346 pub fn takes_values(&self) -> bool { 347 match self { 348 Self::Set => true, 349 Self::Append => true, 350 Self::SetTrue => false, 351 Self::SetFalse => false, 352 Self::Count => false, 353 Self::Help => false, 354 Self::HelpShort => false, 355 Self::HelpLong => false, 356 Self::Version => false, 357 } 358 } 359 default_value(&self) -> Option<&'static std::ffi::OsStr>360 pub(crate) fn default_value(&self) -> Option<&'static std::ffi::OsStr> { 361 match self { 362 Self::Set => None, 363 Self::Append => None, 364 Self::SetTrue => Some(std::ffi::OsStr::new("false")), 365 Self::SetFalse => Some(std::ffi::OsStr::new("true")), 366 Self::Count => Some(std::ffi::OsStr::new("0")), 367 Self::Help => None, 368 Self::HelpShort => None, 369 Self::HelpLong => None, 370 Self::Version => None, 371 } 372 } 373 default_missing_value(&self) -> Option<&'static std::ffi::OsStr>374 pub(crate) fn default_missing_value(&self) -> Option<&'static std::ffi::OsStr> { 375 match self { 376 Self::Set => None, 377 Self::Append => None, 378 Self::SetTrue => Some(std::ffi::OsStr::new("true")), 379 Self::SetFalse => Some(std::ffi::OsStr::new("false")), 380 Self::Count => None, 381 Self::Help => None, 382 Self::HelpShort => None, 383 Self::HelpLong => None, 384 Self::Version => None, 385 } 386 } 387 default_value_parser(&self) -> Option<super::ValueParser>388 pub(crate) fn default_value_parser(&self) -> Option<super::ValueParser> { 389 match self { 390 Self::Set => None, 391 Self::Append => None, 392 Self::SetTrue => Some(super::ValueParser::bool()), 393 Self::SetFalse => Some(super::ValueParser::bool()), 394 Self::Count => Some(crate::value_parser!(u8).into()), 395 Self::Help => None, 396 Self::HelpShort => None, 397 Self::HelpLong => None, 398 Self::Version => None, 399 } 400 } 401 402 #[cfg(debug_assertions)] value_type_id(&self) -> Option<AnyValueId>403 pub(crate) fn value_type_id(&self) -> Option<AnyValueId> { 404 match self { 405 Self::Set => None, 406 Self::Append => None, 407 Self::SetTrue => None, 408 Self::SetFalse => None, 409 Self::Count => Some(AnyValueId::of::<CountType>()), 410 Self::Help => None, 411 Self::HelpShort => None, 412 Self::HelpLong => None, 413 Self::Version => None, 414 } 415 } 416 } 417 418 pub(crate) type CountType = u8; 419