#[non_exhaustive]
pub enum ErrorKind {
Show 17 variants
InvalidValue,
UnknownArgument,
InvalidSubcommand,
NoEquals,
ValueValidation,
TooManyValues,
TooFewValues,
WrongNumberOfValues,
ArgumentConflict,
MissingRequiredArgument,
MissingSubcommand,
InvalidUtf8,
DisplayHelp,
DisplayHelpOnMissingArgumentOrSubcommand,
DisplayVersion,
Io,
Format,
}
Expand description
Command line argument parser kind of error
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
InvalidValue
Occurs when an Arg
has a set of possible values,
and the user provides a value which isn’t in that set.
Examples
let result = Command::new("prog")
.arg(Arg::new("speed")
.value_parser(["fast", "slow"]))
.try_get_matches_from(vec!["prog", "other"]);
assert!(result.is_err());
assert_eq!(result.unwrap_err().kind(), ErrorKind::InvalidValue);
UnknownArgument
Occurs when a user provides a flag, option, argument or subcommand which isn’t defined.
Examples
let result = Command::new("prog")
.arg(arg!(--flag "some flag"))
.try_get_matches_from(vec!["prog", "--other"]);
assert!(result.is_err());
assert_eq!(result.unwrap_err().kind(), ErrorKind::UnknownArgument);
InvalidSubcommand
Occurs when the user provides an unrecognized Subcommand
which meets the threshold for
being similar enough to an existing subcommand.
If it doesn’t meet the threshold, or the ‘suggestions’ feature is disabled,
the more general UnknownArgument
error is returned.
Examples
let result = Command::new("prog")
.subcommand(Command::new("config")
.about("Used for configuration")
.arg(Arg::new("config_file")
.help("The configuration file to use")))
.try_get_matches_from(vec!["prog", "confi"]);
assert!(result.is_err());
assert_eq!(result.unwrap_err().kind(), ErrorKind::InvalidSubcommand);
NoEquals
Occurs when the user doesn’t use equals for an option that requires equal sign to provide values.
let res = Command::new("prog")
.arg(Arg::new("color")
.action(ArgAction::Set)
.require_equals(true)
.long("color"))
.try_get_matches_from(vec!["prog", "--color", "red"]);
assert!(res.is_err());
assert_eq!(res.unwrap_err().kind(), ErrorKind::NoEquals);
ValueValidation
Occurs when the user provides a value for an argument with a custom validation and the value fails that validation.
Examples
fn is_numeric(val: &str) -> Result<(), String> {
match val.parse::<i64>() {
Ok(..) => Ok(()),
Err(..) => Err(String::from("Value wasn't a number!")),
}
}
let result = Command::new("prog")
.arg(Arg::new("num")
.value_parser(value_parser!(u8)))
.try_get_matches_from(vec!["prog", "NotANumber"]);
assert!(result.is_err());
assert_eq!(result.unwrap_err().kind(), ErrorKind::ValueValidation);
TooManyValues
Occurs when a user provides more values for an argument than were defined by setting
Arg::num_args
.
Examples
let result = Command::new("prog")
.arg(Arg::new("arg")
.num_args(1..=2))
.try_get_matches_from(vec!["prog", "too", "many", "values"]);
assert!(result.is_err());
assert_eq!(result.unwrap_err().kind(), ErrorKind::TooManyValues);
TooFewValues
Occurs when the user provides fewer values for an argument than were defined by setting
Arg::num_args
.
Examples
let result = Command::new("prog")
.arg(Arg::new("some_opt")
.long("opt")
.num_args(3..))
.try_get_matches_from(vec!["prog", "--opt", "too", "few"]);
assert!(result.is_err());
assert_eq!(result.unwrap_err().kind(), ErrorKind::TooFewValues);
WrongNumberOfValues
Occurs when the user provides a different number of values for an argument than what’s
been defined by setting Arg::num_args
or than was implicitly set by
Arg::value_names
.
Examples
let result = Command::new("prog")
.arg(Arg::new("some_opt")
.long("opt")
.action(ArgAction::Set)
.num_args(2))
.try_get_matches_from(vec!["prog", "--opt", "wrong"]);
assert!(result.is_err());
assert_eq!(result.unwrap_err().kind(), ErrorKind::WrongNumberOfValues);
ArgumentConflict
Occurs when the user provides two values which conflict with each other and can’t be used together.
Examples
let result = Command::new("prog")
.arg(Arg::new("debug")
.long("debug")
.action(ArgAction::SetTrue)
.conflicts_with("color"))
.arg(Arg::new("color")
.long("color")
.action(ArgAction::SetTrue))
.try_get_matches_from(vec!["prog", "--debug", "--color"]);
assert!(result.is_err());
assert_eq!(result.unwrap_err().kind(), ErrorKind::ArgumentConflict);
MissingRequiredArgument
Occurs when the user does not provide one or more required arguments.
Examples
let result = Command::new("prog")
.arg(Arg::new("debug")
.required(true))
.try_get_matches_from(vec!["prog"]);
assert!(result.is_err());
assert_eq!(result.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
MissingSubcommand
Occurs when a subcommand is required (as defined by Command::subcommand_required
),
but the user does not provide one.
Examples
let err = Command::new("prog")
.subcommand_required(true)
.subcommand(Command::new("test"))
.try_get_matches_from(vec![
"myprog",
]);
assert!(err.is_err());
assert_eq!(err.unwrap_err().kind(), ErrorKind::MissingSubcommand);
InvalidUtf8
Occurs when the user provides a value containing invalid UTF-8.
To allow arbitrary data
- Set [
Arg::value_parser(value_parser!(OsString))
] for argument values - Set
Command::external_subcommand_value_parser
for external-subcommand values
Platform Specific
Non-Windows platforms only (such as Linux, Unix, OSX, etc.)
Examples
let result = Command::new("prog")
.arg(Arg::new("utf8")
.short('u')
.action(ArgAction::Set))
.try_get_matches_from(vec![OsString::from("myprog"),
OsString::from("-u"),
OsString::from_vec(vec![0xE9])]);
assert!(result.is_err());
assert_eq!(result.unwrap_err().kind(), ErrorKind::InvalidUtf8);
DisplayHelp
Not a true “error” as it means --help
or similar was used.
The help message will be sent to stdout
.
Note: If the help is displayed due to an error (such as missing subcommands) it will
be sent to stderr
instead of stdout
.
Examples
let result = Command::new("prog")
.try_get_matches_from(vec!["prog", "--help"]);
assert!(result.is_err());
assert_eq!(result.unwrap_err().kind(), ErrorKind::DisplayHelp);
DisplayHelpOnMissingArgumentOrSubcommand
Occurs when either an argument or a Subcommand
is required, as defined by
Command::arg_required_else_help
, but the user did not provide
one.
Examples
let result = Command::new("prog")
.arg_required_else_help(true)
.subcommand(Command::new("config")
.about("Used for configuration")
.arg(Arg::new("config_file")
.help("The configuration file to use")))
.try_get_matches_from(vec!["prog"]);
assert!(result.is_err());
assert_eq!(result.unwrap_err().kind(), ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand);
DisplayVersion
Not a true “error” as it means --version
or similar was used.
The message will be sent to stdout
.
Examples
let result = Command::new("prog")
.version("3.0")
.try_get_matches_from(vec!["prog", "--version"]);
assert!(result.is_err());
assert_eq!(result.unwrap_err().kind(), ErrorKind::DisplayVersion);
Io
Represents an I/O error.
Can occur when writing to stderr
or stdout
or reading a configuration file.
Format
Represents a Format error (which is a part of Display
).
Typically caused by writing to stderr
or stdout
.
Implementations§
source§impl ErrorKind
impl ErrorKind
sourcepub fn as_str(self) -> Option<&'static str>
pub fn as_str(self) -> Option<&'static str>
End-user description of the error case, where relevant
Examples found in repository?
More examples
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
fn format_error(error: &crate::error::Error<Self>) -> StyledStr {
let mut styled = StyledStr::new();
start_error(&mut styled);
if let Some(msg) = error.kind().as_str() {
styled.none(msg.to_owned());
} else if let Some(source) = error.inner.source.as_ref() {
styled.none(source.to_string());
} else {
styled.none("Unknown cause");
}
styled.none("\n");
styled
}
}
/// Richly formatted error context
#[non_exhaustive]
#[cfg(feature = "error-context")]
pub struct RichFormatter;
#[cfg(feature = "error-context")]
impl ErrorFormatter for RichFormatter {
fn format_error(error: &crate::error::Error<Self>) -> StyledStr {
let mut styled = StyledStr::new();
start_error(&mut styled);
if !write_dynamic_context(error, &mut styled) {
if let Some(msg) = error.kind().as_str() {
styled.none(msg.to_owned());
} else if let Some(source) = error.inner.source.as_ref() {
styled.none(source.to_string());
} else {
styled.none("Unknown cause");
}
}
if let Some(valid) = error.get(ContextKind::SuggestedSubcommand) {
styled.none("\n\n");
did_you_mean(&mut styled, valid);
}
if let Some(valid) = error.get(ContextKind::SuggestedArg) {
styled.none("\n\n");
did_you_mean(&mut styled, valid);
}
if let Some(valid) = error.get(ContextKind::SuggestedValue) {
styled.none("\n\n");
did_you_mean(&mut styled, valid);
}
let suggestions = error.get(ContextKind::Suggested);
if let Some(ContextValue::StyledStrs(suggestions)) = suggestions {
for suggestion in suggestions {
styled.none("\n\n");
styled.none(TAB);
styled.extend(suggestion.iter());
}
}
let usage = error.get(ContextKind::Usage);
if let Some(ContextValue::StyledStr(usage)) = usage {
put_usage(&mut styled, usage.clone());
}
try_help(&mut styled, error.inner.help_flag);
styled
}