| 1 | /// Command line argument parser kind of error | 
| 2 | #[ derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] | 
|---|
| 3 | #[ non_exhaustive] | 
|---|
| 4 | pub enum ErrorKind { | 
|---|
| 5 | /// Occurs when an [`Arg`][crate::Arg] has a set of possible values, | 
|---|
| 6 | /// and the user provides a value which isn't in that set. | 
|---|
| 7 | /// | 
|---|
| 8 | /// # Examples | 
|---|
| 9 | /// | 
|---|
| 10 | /// ```rust | 
|---|
| 11 | /// # use clap_builder as clap; | 
|---|
| 12 | /// # use clap::{Command, Arg, error::ErrorKind}; | 
|---|
| 13 | /// let result = Command::new( "prog") | 
|---|
| 14 | ///     .arg(Arg::new( "speed") | 
|---|
| 15 | ///         .value_parser([ "fast", "slow"])) | 
|---|
| 16 | ///     .try_get_matches_from(vec![ "prog", "other"]); | 
|---|
| 17 | /// assert!(result.is_err()); | 
|---|
| 18 | /// assert_eq!(result.unwrap_err().kind(), ErrorKind::InvalidValue); | 
|---|
| 19 | /// ``` | 
|---|
| 20 | InvalidValue, | 
|---|
| 21 |  | 
|---|
| 22 | /// Occurs when a user provides a flag, option, argument or subcommand which isn't defined. | 
|---|
| 23 | /// | 
|---|
| 24 | /// # Examples | 
|---|
| 25 | /// | 
|---|
| 26 | /// ```rust | 
|---|
| 27 | /// # use clap_builder as clap; | 
|---|
| 28 | /// # use clap::{Command, arg, error::ErrorKind}; | 
|---|
| 29 | /// let result = Command::new( "prog") | 
|---|
| 30 | ///     .arg(arg!(--flag "some flag")) | 
|---|
| 31 | ///     .try_get_matches_from(vec![ "prog", "--other"]); | 
|---|
| 32 | /// assert!(result.is_err()); | 
|---|
| 33 | /// assert_eq!(result.unwrap_err().kind(), ErrorKind::UnknownArgument); | 
|---|
| 34 | /// ``` | 
|---|
| 35 | UnknownArgument, | 
|---|
| 36 |  | 
|---|
| 37 | /// Occurs when the user provides an unrecognized [`Subcommand`] which meets the threshold for | 
|---|
| 38 | /// being similar enough to an existing subcommand. | 
|---|
| 39 | /// If it doesn't meet the threshold, or the 'suggestions' feature is disabled, | 
|---|
| 40 | /// the more general [`UnknownArgument`] error is returned. | 
|---|
| 41 | /// | 
|---|
| 42 | /// # Examples | 
|---|
| 43 | /// | 
|---|
| 44 | /// ```rust | 
|---|
| 45 | /// # #[ cfg(feature = "suggestions")] { | 
|---|
| 46 | /// # use clap_builder as clap; | 
|---|
| 47 | /// # use clap::{Command, Arg, error::ErrorKind, }; | 
|---|
| 48 | /// let result = Command::new( "prog") | 
|---|
| 49 | ///     .subcommand(Command::new( "config") | 
|---|
| 50 | ///         .about( "Used for configuration") | 
|---|
| 51 | ///         .arg(Arg::new( "config_file") | 
|---|
| 52 | ///             .help( "The configuration file to use"))) | 
|---|
| 53 | ///     .try_get_matches_from(vec![ "prog", "confi"]); | 
|---|
| 54 | /// assert!(result.is_err()); | 
|---|
| 55 | /// assert_eq!(result.unwrap_err().kind(), ErrorKind::InvalidSubcommand); | 
|---|
| 56 | /// # } | 
|---|
| 57 | /// ``` | 
|---|
| 58 | /// | 
|---|
| 59 | /// [`Subcommand`]: crate::Subcommand | 
|---|
| 60 | /// [`UnknownArgument`]: ErrorKind::UnknownArgument | 
|---|
| 61 | InvalidSubcommand, | 
|---|
| 62 |  | 
|---|
| 63 | /// Occurs when the user doesn't use equals for an option that requires equal | 
|---|
| 64 | /// sign to provide values. | 
|---|
| 65 | /// | 
|---|
| 66 | /// ```rust | 
|---|
| 67 | /// # use clap_builder as clap; | 
|---|
| 68 | /// # use clap::{Command, Arg, error::ErrorKind, ArgAction}; | 
|---|
| 69 | /// let res = Command::new( "prog") | 
|---|
| 70 | ///     .arg(Arg::new( "color") | 
|---|
| 71 | ///          .action(ArgAction::Set) | 
|---|
| 72 | ///          .require_equals(true) | 
|---|
| 73 | ///          .long( "color")) | 
|---|
| 74 | ///     .try_get_matches_from(vec![ "prog", "--color", "red"]); | 
|---|
| 75 | /// assert!(res.is_err()); | 
|---|
| 76 | /// assert_eq!(res.unwrap_err().kind(), ErrorKind::NoEquals); | 
|---|
| 77 | /// ``` | 
|---|
| 78 | NoEquals, | 
|---|
| 79 |  | 
|---|
| 80 | /// Occurs when the user provides a value for an argument with a custom validation and the | 
|---|
| 81 | /// value fails that validation. | 
|---|
| 82 | /// | 
|---|
| 83 | /// # Examples | 
|---|
| 84 | /// | 
|---|
| 85 | /// ```rust | 
|---|
| 86 | /// # use clap_builder as clap; | 
|---|
| 87 | /// # use clap::{Command, Arg, error::ErrorKind, value_parser}; | 
|---|
| 88 | /// fn is_numeric(val: &str) -> Result<(), String> { | 
|---|
| 89 | ///     match val.parse::<i64>() { | 
|---|
| 90 | ///         Ok(..) => Ok(()), | 
|---|
| 91 | ///         Err(..) => Err(String::from( "value wasn't a number!")), | 
|---|
| 92 | ///     } | 
|---|
| 93 | /// } | 
|---|
| 94 | /// | 
|---|
| 95 | /// let result = Command::new( "prog") | 
|---|
| 96 | ///     .arg(Arg::new( "num") | 
|---|
| 97 | ///          .value_parser(value_parser!(u8))) | 
|---|
| 98 | ///     .try_get_matches_from(vec![ "prog", "NotANumber"]); | 
|---|
| 99 | /// assert!(result.is_err()); | 
|---|
| 100 | /// assert_eq!(result.unwrap_err().kind(), ErrorKind::ValueValidation); | 
|---|
| 101 | /// ``` | 
|---|
| 102 | ValueValidation, | 
|---|
| 103 |  | 
|---|
| 104 | /// Occurs when a user provides more values for an argument than were defined by setting | 
|---|
| 105 | /// [`Arg::num_args`]. | 
|---|
| 106 | /// | 
|---|
| 107 | /// # Examples | 
|---|
| 108 | /// | 
|---|
| 109 | /// ```rust | 
|---|
| 110 | /// # use clap_builder as clap; | 
|---|
| 111 | /// # use clap::{Command, Arg, error::ErrorKind}; | 
|---|
| 112 | /// let result = Command::new( "prog") | 
|---|
| 113 | ///     .arg(Arg::new( "arg") | 
|---|
| 114 | ///         .num_args(1..=2)) | 
|---|
| 115 | ///     .try_get_matches_from(vec![ "prog", "too", "many", "values"]); | 
|---|
| 116 | /// assert!(result.is_err()); | 
|---|
| 117 | /// assert_eq!(result.unwrap_err().kind(), ErrorKind::TooManyValues); | 
|---|
| 118 | /// ``` | 
|---|
| 119 | /// [`Arg::num_args`]: crate::Arg::num_args() | 
|---|
| 120 | TooManyValues, | 
|---|
| 121 |  | 
|---|
| 122 | /// Occurs when the user provides fewer values for an argument than were defined by setting | 
|---|
| 123 | /// [`Arg::num_args`]. | 
|---|
| 124 | /// | 
|---|
| 125 | /// # Examples | 
|---|
| 126 | /// | 
|---|
| 127 | /// ```rust | 
|---|
| 128 | /// # use clap_builder as clap; | 
|---|
| 129 | /// # use clap::{Command, Arg, error::ErrorKind}; | 
|---|
| 130 | /// let result = Command::new( "prog") | 
|---|
| 131 | ///     .arg(Arg::new( "some_opt") | 
|---|
| 132 | ///         .long( "opt") | 
|---|
| 133 | ///         .num_args(3..)) | 
|---|
| 134 | ///     .try_get_matches_from(vec![ "prog", "--opt", "too", "few"]); | 
|---|
| 135 | /// assert!(result.is_err()); | 
|---|
| 136 | /// assert_eq!(result.unwrap_err().kind(), ErrorKind::TooFewValues); | 
|---|
| 137 | /// ``` | 
|---|
| 138 | /// [`Arg::num_args`]: crate::Arg::num_args() | 
|---|
| 139 | TooFewValues, | 
|---|
| 140 |  | 
|---|
| 141 | /// Occurs when the user provides a different number of values for an argument than what's | 
|---|
| 142 | /// been defined by setting [`Arg::num_args`] or than was implicitly set by | 
|---|
| 143 | /// [`Arg::value_names`]. | 
|---|
| 144 | /// | 
|---|
| 145 | /// # Examples | 
|---|
| 146 | /// | 
|---|
| 147 | /// ```rust | 
|---|
| 148 | /// # use clap_builder as clap; | 
|---|
| 149 | /// # use clap::{Command, Arg, error::ErrorKind, ArgAction}; | 
|---|
| 150 | /// let result = Command::new( "prog") | 
|---|
| 151 | ///     .arg(Arg::new( "some_opt") | 
|---|
| 152 | ///         .long( "opt") | 
|---|
| 153 | ///         .action(ArgAction::Set) | 
|---|
| 154 | ///         .num_args(2)) | 
|---|
| 155 | ///     .try_get_matches_from(vec![ "prog", "--opt", "wrong"]); | 
|---|
| 156 | /// assert!(result.is_err()); | 
|---|
| 157 | /// assert_eq!(result.unwrap_err().kind(), ErrorKind::WrongNumberOfValues); | 
|---|
| 158 | /// ``` | 
|---|
| 159 | /// | 
|---|
| 160 | /// [`Arg::num_args`]: crate::Arg::num_args() | 
|---|
| 161 | /// [`Arg::value_names`]: crate::Arg::value_names() | 
|---|
| 162 | WrongNumberOfValues, | 
|---|
| 163 |  | 
|---|
| 164 | /// Occurs when the user provides two values which conflict with each other and can't be used | 
|---|
| 165 | /// together. | 
|---|
| 166 | /// | 
|---|
| 167 | /// # Examples | 
|---|
| 168 | /// | 
|---|
| 169 | /// ```rust | 
|---|
| 170 | /// # use clap_builder as clap; | 
|---|
| 171 | /// # use clap::{Command, Arg, error::ErrorKind, ArgAction}; | 
|---|
| 172 | /// let result = Command::new( "prog") | 
|---|
| 173 | ///     .arg(Arg::new( "debug") | 
|---|
| 174 | ///         .long( "debug") | 
|---|
| 175 | ///         .action(ArgAction::SetTrue) | 
|---|
| 176 | ///         .conflicts_with( "color")) | 
|---|
| 177 | ///     .arg(Arg::new( "color") | 
|---|
| 178 | ///         .long( "color") | 
|---|
| 179 | ///         .action(ArgAction::SetTrue)) | 
|---|
| 180 | ///     .try_get_matches_from(vec![ "prog", "--debug", "--color"]); | 
|---|
| 181 | /// assert!(result.is_err()); | 
|---|
| 182 | /// assert_eq!(result.unwrap_err().kind(), ErrorKind::ArgumentConflict); | 
|---|
| 183 | /// ``` | 
|---|
| 184 | ArgumentConflict, | 
|---|
| 185 |  | 
|---|
| 186 | /// Occurs when the user does not provide one or more required arguments. | 
|---|
| 187 | /// | 
|---|
| 188 | /// # Examples | 
|---|
| 189 | /// | 
|---|
| 190 | /// ```rust | 
|---|
| 191 | /// # use clap_builder as clap; | 
|---|
| 192 | /// # use clap::{Command, Arg, error::ErrorKind}; | 
|---|
| 193 | /// let result = Command::new( "prog") | 
|---|
| 194 | ///     .arg(Arg::new( "debug") | 
|---|
| 195 | ///         .required(true)) | 
|---|
| 196 | ///     .try_get_matches_from(vec![ "prog"]); | 
|---|
| 197 | /// assert!(result.is_err()); | 
|---|
| 198 | /// assert_eq!(result.unwrap_err().kind(), ErrorKind::MissingRequiredArgument); | 
|---|
| 199 | /// ``` | 
|---|
| 200 | MissingRequiredArgument, | 
|---|
| 201 |  | 
|---|
| 202 | /// Occurs when a subcommand is required (as defined by [`Command::subcommand_required`]), | 
|---|
| 203 | /// but the user does not provide one. | 
|---|
| 204 | /// | 
|---|
| 205 | /// # Examples | 
|---|
| 206 | /// | 
|---|
| 207 | /// ```rust | 
|---|
| 208 | /// # use clap_builder as clap; | 
|---|
| 209 | /// # use clap::{Command, error::ErrorKind}; | 
|---|
| 210 | /// let err = Command::new( "prog") | 
|---|
| 211 | ///     .subcommand_required(true) | 
|---|
| 212 | ///     .subcommand(Command::new( "test")) | 
|---|
| 213 | ///     .try_get_matches_from(vec![ | 
|---|
| 214 | /// "myprog", | 
|---|
| 215 | ///     ]); | 
|---|
| 216 | /// assert!(err.is_err()); | 
|---|
| 217 | /// assert_eq!(err.unwrap_err().kind(), ErrorKind::MissingSubcommand); | 
|---|
| 218 | /// # ; | 
|---|
| 219 | /// ``` | 
|---|
| 220 | /// | 
|---|
| 221 | /// [`Command::subcommand_required`]: crate::Command::subcommand_required | 
|---|
| 222 | MissingSubcommand, | 
|---|
| 223 |  | 
|---|
| 224 | /// Occurs when the user provides a value containing invalid UTF-8. | 
|---|
| 225 | /// | 
|---|
| 226 | /// To allow arbitrary data | 
|---|
| 227 | /// - Set [`Arg::value_parser(value_parser!(OsString))`] for argument values | 
|---|
| 228 | /// - Set [`Command::external_subcommand_value_parser`] for external-subcommand | 
|---|
| 229 | ///   values | 
|---|
| 230 | /// | 
|---|
| 231 | /// # Platform Specific | 
|---|
| 232 | /// | 
|---|
| 233 | /// Non-Windows platforms only (such as Linux, Unix, OSX, etc.) | 
|---|
| 234 | /// | 
|---|
| 235 | /// # Examples | 
|---|
| 236 | /// | 
|---|
| 237 | /// ```rust | 
|---|
| 238 | /// # #[ cfg(unix)] { | 
|---|
| 239 | /// # use clap_builder as clap; | 
|---|
| 240 | /// # use clap::{Command, Arg, error::ErrorKind, ArgAction}; | 
|---|
| 241 | /// # use std::os::unix::ffi::OsStringExt; | 
|---|
| 242 | /// # use std::ffi::OsString; | 
|---|
| 243 | /// let result = Command::new( "prog") | 
|---|
| 244 | ///     .arg(Arg::new( "utf8") | 
|---|
| 245 | ///         .short( 'u') | 
|---|
| 246 | ///         .action(ArgAction::Set)) | 
|---|
| 247 | ///     .try_get_matches_from(vec![OsString::from( "myprog"), | 
|---|
| 248 | ///                                 OsString::from( "-u"), | 
|---|
| 249 | ///                                 OsString::from_vec(vec![0xE9])]); | 
|---|
| 250 | /// assert!(result.is_err()); | 
|---|
| 251 | /// assert_eq!(result.unwrap_err().kind(), ErrorKind::InvalidUtf8); | 
|---|
| 252 | /// # } | 
|---|
| 253 | /// ``` | 
|---|
| 254 | /// | 
|---|
| 255 | /// [`Arg::allow_invalid_utf8`]: crate::Arg::allow_invalid_utf8 | 
|---|
| 256 | /// [`Command::external_subcommand_value_parser`]: crate::Command::external_subcommand_value_parser | 
|---|
| 257 | InvalidUtf8, | 
|---|
| 258 |  | 
|---|
| 259 | /// Not a true "error" as it means `--help` or similar was used. | 
|---|
| 260 | /// The help message will be sent to `stdout`. | 
|---|
| 261 | /// | 
|---|
| 262 | /// **Note**: If the help is displayed due to an error (such as missing subcommands) it will | 
|---|
| 263 | /// be sent to `stderr` instead of `stdout`. | 
|---|
| 264 | /// | 
|---|
| 265 | /// # Examples | 
|---|
| 266 | /// | 
|---|
| 267 | /// ```rust | 
|---|
| 268 | /// # #[ cfg(feature = "help")] { | 
|---|
| 269 | /// # use clap_builder as clap; | 
|---|
| 270 | /// # use clap::{Command, Arg, error::ErrorKind}; | 
|---|
| 271 | /// let result = Command::new( "prog") | 
|---|
| 272 | ///     .try_get_matches_from(vec![ "prog", "--help"]); | 
|---|
| 273 | /// assert!(result.is_err()); | 
|---|
| 274 | /// assert_eq!(result.unwrap_err().kind(), ErrorKind::DisplayHelp); | 
|---|
| 275 | /// # } | 
|---|
| 276 | /// ``` | 
|---|
| 277 | DisplayHelp, | 
|---|
| 278 |  | 
|---|
| 279 | /// Occurs when either an argument or a [`Subcommand`] is required, as defined by | 
|---|
| 280 | /// [`Command::arg_required_else_help`] , but the user did not provide | 
|---|
| 281 | /// one. | 
|---|
| 282 | /// | 
|---|
| 283 | /// # Examples | 
|---|
| 284 | /// | 
|---|
| 285 | /// ```rust | 
|---|
| 286 | /// # use clap_builder as clap; | 
|---|
| 287 | /// # use clap::{Command, Arg, error::ErrorKind, }; | 
|---|
| 288 | /// let result = Command::new( "prog") | 
|---|
| 289 | ///     .arg_required_else_help(true) | 
|---|
| 290 | ///     .subcommand(Command::new( "config") | 
|---|
| 291 | ///         .about( "Used for configuration") | 
|---|
| 292 | ///         .arg(Arg::new( "config_file") | 
|---|
| 293 | ///             .help( "The configuration file to use"))) | 
|---|
| 294 | ///     .try_get_matches_from(vec![ "prog"]); | 
|---|
| 295 | /// assert!(result.is_err()); | 
|---|
| 296 | /// assert_eq!(result.unwrap_err().kind(), ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand); | 
|---|
| 297 | /// ``` | 
|---|
| 298 | /// | 
|---|
| 299 | /// [`Subcommand`]: crate::Subcommand | 
|---|
| 300 | /// [`Command::arg_required_else_help`]: crate::Command::arg_required_else_help | 
|---|
| 301 | DisplayHelpOnMissingArgumentOrSubcommand, | 
|---|
| 302 |  | 
|---|
| 303 | /// Not a true "error" as it means `--version` or similar was used. | 
|---|
| 304 | /// The message will be sent to `stdout`. | 
|---|
| 305 | /// | 
|---|
| 306 | /// # Examples | 
|---|
| 307 | /// | 
|---|
| 308 | /// ```rust | 
|---|
| 309 | /// # use clap_builder as clap; | 
|---|
| 310 | /// # use clap::{Command, Arg, error::ErrorKind}; | 
|---|
| 311 | /// let result = Command::new( "prog") | 
|---|
| 312 | ///     .version( "3.0") | 
|---|
| 313 | ///     .try_get_matches_from(vec![ "prog", "--version"]); | 
|---|
| 314 | /// assert!(result.is_err()); | 
|---|
| 315 | /// assert_eq!(result.unwrap_err().kind(), ErrorKind::DisplayVersion); | 
|---|
| 316 | /// ``` | 
|---|
| 317 | DisplayVersion, | 
|---|
| 318 |  | 
|---|
| 319 | /// Represents an [I/O error]. | 
|---|
| 320 | /// Can occur when writing to `stderr` or `stdout` or reading a configuration file. | 
|---|
| 321 | /// | 
|---|
| 322 | /// [I/O error]: std::io::Error | 
|---|
| 323 | Io, | 
|---|
| 324 |  | 
|---|
| 325 | /// Represents a [Format error] (which is a part of [`Display`]). | 
|---|
| 326 | /// Typically caused by writing to `stderr` or `stdout`. | 
|---|
| 327 | /// | 
|---|
| 328 | /// [`Display`]: std::fmt::Display | 
|---|
| 329 | /// [Format error]: std::fmt::Error | 
|---|
| 330 | Format, | 
|---|
| 331 | } | 
|---|
| 332 |  | 
|---|
| 333 | impl ErrorKind { | 
|---|
| 334 | /// End-user description of the error case, where relevant | 
|---|
| 335 | pub fn as_str(self) -> Option<&'static str> { | 
|---|
| 336 | match self { | 
|---|
| 337 | Self::InvalidValue => Some( "one of the values isn't valid for an argument"), | 
|---|
| 338 | Self::UnknownArgument => Some( "unexpected argument found"), | 
|---|
| 339 | Self::InvalidSubcommand => Some( "unrecognized subcommand"), | 
|---|
| 340 | Self::NoEquals => Some( "equal is needed when assigning values to one of the arguments"), | 
|---|
| 341 | Self::ValueValidation => Some( "invalid value for one of the arguments"), | 
|---|
| 342 | Self::TooManyValues => Some( "unexpected value for an argument found"), | 
|---|
| 343 | Self::TooFewValues => Some( "more values required for an argument"), | 
|---|
| 344 | Self::WrongNumberOfValues => Some( "too many or too few values for an argument"), | 
|---|
| 345 | Self::ArgumentConflict => { | 
|---|
| 346 | Some( "an argument cannot be used with one or more of the other specified arguments") | 
|---|
| 347 | } | 
|---|
| 348 | Self::MissingRequiredArgument => { | 
|---|
| 349 | Some( "one or more required arguments were not provided") | 
|---|
| 350 | } | 
|---|
| 351 | Self::MissingSubcommand => Some( "a subcommand is required but one was not provided"), | 
|---|
| 352 | Self::InvalidUtf8 => Some( "invalid UTF-8 was detected in one or more arguments"), | 
|---|
| 353 | Self::DisplayHelp => None, | 
|---|
| 354 | Self::DisplayHelpOnMissingArgumentOrSubcommand => None, | 
|---|
| 355 | Self::DisplayVersion => None, | 
|---|
| 356 | Self::Io => None, | 
|---|
| 357 | Self::Format => None, | 
|---|
| 358 | } | 
|---|
| 359 | } | 
|---|
| 360 | } | 
|---|
| 361 |  | 
|---|
| 362 | impl std::fmt::Display for ErrorKind { | 
|---|
| 363 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | 
|---|
| 364 | self.as_str().unwrap_or_default().fmt(f) | 
|---|
| 365 | } | 
|---|
| 366 | } | 
|---|
| 367 |  | 
|---|