You've already forked uutils-args
mirror of
https://github.com/uutils/uutils-args.git
synced 2026-06-10 16:13:08 -07:00
add simple error messages (with a lot of room for improvement)
This commit is contained in:
@@ -26,9 +26,10 @@ struct Settings {
|
||||
count: u8,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let settings = Settings::parse(std::env::args_os()).unwrap();
|
||||
fn main() -> Result<(), uutils_args::Error> {
|
||||
let settings = Settings::parse(std::env::args_os());
|
||||
for _ in 0..settings.count {
|
||||
println!("Hello, {}!", settings.name);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
use std::{
|
||||
error::Error as StdError,
|
||||
ffi::OsString,
|
||||
fmt::{Debug, Display},
|
||||
};
|
||||
|
||||
pub enum Error {
|
||||
MissingValue {
|
||||
option: Option<String>,
|
||||
},
|
||||
MissingPositionalArguments(Vec<String>),
|
||||
UnexpectedOption(String),
|
||||
UnexpectedArgument(OsString),
|
||||
UnexpectedValue {
|
||||
option: String,
|
||||
value: OsString,
|
||||
},
|
||||
ParsingFailed {
|
||||
option: String,
|
||||
value: String,
|
||||
error: Box<dyn StdError + Send + Sync + 'static>,
|
||||
},
|
||||
AmbiguousOption {
|
||||
option: String,
|
||||
candidates: Vec<String>,
|
||||
},
|
||||
AmbiguousValue {
|
||||
option: String,
|
||||
value: String,
|
||||
candidates: Vec<String>,
|
||||
},
|
||||
NonUnicodeValue(OsString),
|
||||
Custom(Box<dyn StdError + Send + Sync + 'static>),
|
||||
}
|
||||
|
||||
impl StdError for Error {}
|
||||
|
||||
impl Debug for Error {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Error {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "error: ")?;
|
||||
match self {
|
||||
Error::MissingValue { option } => match option {
|
||||
Some(option) => write!(f, "Missing value for '{option}'."),
|
||||
None => write!(f, "Missing value"),
|
||||
},
|
||||
Error::MissingPositionalArguments(args) => {
|
||||
write!(f, "Missing values for the following positional arguments:")?;
|
||||
for arg in args {
|
||||
write!(f, " - {arg}")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Error::UnexpectedOption(opt) => {
|
||||
write!(f, "Found an invalid option '{opt}'.")
|
||||
}
|
||||
Error::UnexpectedArgument(arg) => {
|
||||
write!(f, "Found an invalid argument '{}'.", arg.to_string_lossy())
|
||||
}
|
||||
Error::UnexpectedValue { option, value } => {
|
||||
write!(
|
||||
f,
|
||||
"Got an unexpected value '{}' for option '{option}'.",
|
||||
value.to_string_lossy(),
|
||||
)
|
||||
}
|
||||
Error::ParsingFailed {
|
||||
option,
|
||||
value,
|
||||
error,
|
||||
} => {
|
||||
if option.is_empty() {
|
||||
write!(f, "Could not parse value '{value}': {error}")
|
||||
} else {
|
||||
write!(
|
||||
f,
|
||||
"Could not parse value '{value}' for option '{option}': {error}"
|
||||
)
|
||||
}
|
||||
}
|
||||
Error::AmbiguousOption { option, candidates } => {
|
||||
write!(
|
||||
f,
|
||||
"Option '{option}' is ambiguous. The following candidates match:"
|
||||
)?;
|
||||
for candidate in candidates {
|
||||
write!(f, " - {candidate}")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Error::AmbiguousValue {
|
||||
option,
|
||||
value,
|
||||
candidates,
|
||||
} => {
|
||||
write!(
|
||||
f,
|
||||
"Value '{value}' for option '{option}' is ambiguous. The following candidates match:",
|
||||
)?;
|
||||
for candidate in candidates {
|
||||
write!(f, " - {candidate}")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Error::NonUnicodeValue(x) => {
|
||||
write!(f, "Invalid unicode value found: {}", x.to_string_lossy())
|
||||
}
|
||||
Error::Custom(err) => std::fmt::Display::fmt(err, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<lexopt::Error> for Error {
|
||||
fn from(other: lexopt::Error) -> Error {
|
||||
match other {
|
||||
lexopt::Error::MissingValue { option } => Self::MissingValue { option },
|
||||
lexopt::Error::UnexpectedOption(s) => Self::UnexpectedOption(s),
|
||||
lexopt::Error::UnexpectedArgument(s) => Self::UnexpectedArgument(s),
|
||||
lexopt::Error::UnexpectedValue { option, value } => {
|
||||
Self::UnexpectedValue { option, value }
|
||||
}
|
||||
lexopt::Error::ParsingFailed { .. } => panic!("Conversion not supported"),
|
||||
lexopt::Error::NonUnicodeValue(s) => Self::NonUnicodeValue(s),
|
||||
lexopt::Error::Custom(e) => Self::Custom(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
+17
-48
@@ -1,58 +1,13 @@
|
||||
mod error;
|
||||
pub use derive::*;
|
||||
pub use lexopt;
|
||||
pub use term_md;
|
||||
|
||||
use std::error::Error as StdError;
|
||||
pub use error::Error;
|
||||
use std::num::ParseIntError;
|
||||
use std::path::PathBuf;
|
||||
use std::{ffi::OsString, marker::PhantomData};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
MissingValue {
|
||||
option: Option<String>,
|
||||
},
|
||||
MissingPositionalArguments(Vec<String>),
|
||||
UnexpectedOption(String),
|
||||
UnexpectedArgument(OsString),
|
||||
UnexpectedValue {
|
||||
option: String,
|
||||
value: OsString,
|
||||
},
|
||||
ParsingFailed {
|
||||
option: String,
|
||||
value: String,
|
||||
error: Box<dyn StdError + Send + Sync + 'static>,
|
||||
},
|
||||
AmbiguousOption {
|
||||
option: String,
|
||||
candidates: Vec<String>,
|
||||
},
|
||||
AmbiguousValue {
|
||||
option: String,
|
||||
value: String,
|
||||
candidates: Vec<String>,
|
||||
},
|
||||
NonUnicodeValue(OsString),
|
||||
Custom(Box<dyn StdError + Send + Sync + 'static>),
|
||||
}
|
||||
|
||||
impl From<lexopt::Error> for Error {
|
||||
fn from(other: lexopt::Error) -> Error {
|
||||
match other {
|
||||
lexopt::Error::MissingValue { option } => Self::MissingValue { option },
|
||||
lexopt::Error::UnexpectedOption(s) => Self::UnexpectedOption(s),
|
||||
lexopt::Error::UnexpectedArgument(s) => Self::UnexpectedArgument(s),
|
||||
lexopt::Error::UnexpectedValue { option, value } => {
|
||||
Self::UnexpectedValue { option, value }
|
||||
}
|
||||
lexopt::Error::ParsingFailed { .. } => panic!("Conversion not supported"),
|
||||
lexopt::Error::NonUnicodeValue(s) => Self::NonUnicodeValue(s),
|
||||
lexopt::Error::Custom(e) => Self::Custom(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum Argument<T: Arguments> {
|
||||
Help,
|
||||
@@ -114,7 +69,21 @@ impl<T: Arguments> ArgumentIter<T> {
|
||||
}
|
||||
|
||||
pub trait Options: Sized + Default {
|
||||
fn parse<I>(args: I) -> Result<Self, Error>
|
||||
fn parse<I>(args: I) -> Self
|
||||
where
|
||||
I: IntoIterator + 'static,
|
||||
I::Item: Into<OsString>,
|
||||
{
|
||||
match Self::try_parse(args) {
|
||||
Ok(v) => v,
|
||||
Err(err) => {
|
||||
eprintln!("{err}");
|
||||
std::process::exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn try_parse<I>(args: I) -> Result<Self, Error>
|
||||
where
|
||||
I: IntoIterator + 'static,
|
||||
I::Item: Into<OsString>,
|
||||
|
||||
@@ -11,12 +11,12 @@ struct Settings {}
|
||||
|
||||
#[test]
|
||||
fn no_args() {
|
||||
assert!(Settings::parse(["arch"]).is_ok());
|
||||
assert!(Settings::try_parse(["arch"]).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn one_arg_fails() {
|
||||
assert!(Settings::parse(["arch", "-f"]).is_err());
|
||||
assert!(Settings::parse(["arch", "--foo"]).is_err());
|
||||
assert!(Settings::parse(["arch", "foo"]).is_err());
|
||||
assert!(Settings::try_parse(["arch", "-f"]).is_err());
|
||||
assert!(Settings::try_parse(["arch", "--foo"]).is_err());
|
||||
assert!(Settings::try_parse(["arch", "foo"]).is_err());
|
||||
}
|
||||
|
||||
+17
-33
@@ -73,64 +73,48 @@ struct Settings {
|
||||
|
||||
#[test]
|
||||
fn binary() {
|
||||
assert!(!Settings::parse(["b2sum"]).unwrap().binary);
|
||||
assert!(!Settings::parse(["b2sum", "--text"]).unwrap().binary);
|
||||
assert!(!Settings::parse(["b2sum", "-t"]).unwrap().binary);
|
||||
assert!(
|
||||
!Settings::parse(["b2sum", "--binary", "--text"])
|
||||
.unwrap()
|
||||
.binary
|
||||
);
|
||||
assert!(!Settings::parse(["b2sum", "-b", "-t"]).unwrap().binary);
|
||||
assert!(!Settings::parse(["b2sum"]).binary);
|
||||
assert!(!Settings::parse(["b2sum", "--text"]).binary);
|
||||
assert!(!Settings::parse(["b2sum", "-t"]).binary);
|
||||
assert!(!Settings::parse(["b2sum", "--binary", "--text"]).binary);
|
||||
assert!(!Settings::parse(["b2sum", "-b", "-t"]).binary);
|
||||
|
||||
assert!(Settings::parse(["b2sum", "--binary"]).unwrap().binary);
|
||||
assert!(Settings::parse(["b2sum", "-b"]).unwrap().binary);
|
||||
assert!(
|
||||
Settings::parse(["b2sum", "--text", "--binary"])
|
||||
.unwrap()
|
||||
.binary
|
||||
);
|
||||
assert!(Settings::parse(["b2sum", "-t", "-b"]).unwrap().binary);
|
||||
assert!(Settings::parse(["b2sum", "--binary"]).binary);
|
||||
assert!(Settings::parse(["b2sum", "-b"]).binary);
|
||||
assert!(Settings::parse(["b2sum", "--text", "--binary"]).binary);
|
||||
assert!(Settings::parse(["b2sum", "-t", "-b"]).binary);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_output() {
|
||||
assert_eq!(
|
||||
Settings::parse(["b2sum", "--warn"]).unwrap().check_output,
|
||||
Settings::parse(["b2sum", "--warn"]).check_output,
|
||||
CheckOutput::Warn
|
||||
);
|
||||
assert_eq!(
|
||||
Settings::parse(["b2sum", "--quiet"]).unwrap().check_output,
|
||||
Settings::parse(["b2sum", "--quiet"]).check_output,
|
||||
CheckOutput::Quiet
|
||||
);
|
||||
assert_eq!(
|
||||
Settings::parse(["b2sum", "--status"]).unwrap().check_output,
|
||||
Settings::parse(["b2sum", "--status"]).check_output,
|
||||
CheckOutput::Status
|
||||
);
|
||||
assert_eq!(
|
||||
Settings::parse(["b2sum", "--status", "--warn"])
|
||||
.unwrap()
|
||||
.check_output,
|
||||
Settings::parse(["b2sum", "--status", "--warn"]).check_output,
|
||||
CheckOutput::Warn
|
||||
);
|
||||
assert_eq!(
|
||||
Settings::parse(["b2sum", "--status", "--warn"])
|
||||
.unwrap()
|
||||
.check_output,
|
||||
Settings::parse(["b2sum", "--status", "--warn"]).check_output,
|
||||
CheckOutput::Warn
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Settings::parse(["b2sum", "--warn", "--quiet"])
|
||||
.unwrap()
|
||||
.check_output,
|
||||
Settings::parse(["b2sum", "--warn", "--quiet"]).check_output,
|
||||
CheckOutput::Quiet
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Settings::parse(["b2sum", "--quiet", "--status"])
|
||||
.unwrap()
|
||||
.check_output,
|
||||
Settings::parse(["b2sum", "--quiet", "--status"]).check_output,
|
||||
CheckOutput::Status
|
||||
);
|
||||
}
|
||||
@@ -138,7 +122,7 @@ fn check_output() {
|
||||
#[test]
|
||||
fn files() {
|
||||
assert_eq!(
|
||||
Settings::parse(["b2sum", "foo", "bar"]).unwrap().files,
|
||||
Settings::parse(["b2sum", "foo", "bar"]).files,
|
||||
vec![Path::new("foo"), Path::new("bar")]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -41,14 +41,8 @@ struct Settings {
|
||||
|
||||
#[test]
|
||||
fn wrap() {
|
||||
assert_eq!(Settings::parse(["base32"]).unwrap().wrap, Some(76));
|
||||
assert_eq!(Settings::parse(["base32", "-w0"]).unwrap().wrap, None);
|
||||
assert_eq!(
|
||||
Settings::parse(["base32", "-w100"]).unwrap().wrap,
|
||||
Some(100)
|
||||
);
|
||||
assert_eq!(
|
||||
Settings::parse(["base32", "--wrap=100"]).unwrap().wrap,
|
||||
Some(100)
|
||||
);
|
||||
assert_eq!(Settings::parse(["base32"]).wrap, Some(76));
|
||||
assert_eq!(Settings::parse(["base32", "-w0"]).wrap, None);
|
||||
assert_eq!(Settings::parse(["base32", "-w100"]).wrap, Some(100));
|
||||
assert_eq!(Settings::parse(["base32", "--wrap=100"]).wrap, Some(100));
|
||||
}
|
||||
|
||||
@@ -33,18 +33,18 @@ struct Settings {
|
||||
names: Vec<String>,
|
||||
}
|
||||
|
||||
fn parse(args: &'static [&'static str]) -> Result<Settings, uutils_args::Error> {
|
||||
let mut settings = Settings::parse(args)?;
|
||||
fn parse(args: &'static [&'static str]) -> Settings {
|
||||
let mut settings = Settings::parse(args);
|
||||
if !settings.multiple {
|
||||
assert_eq!(settings.names.len(), 2);
|
||||
settings.suffix = settings.names.pop().unwrap();
|
||||
}
|
||||
Ok(settings)
|
||||
settings
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn name_and_suffix() {
|
||||
let settings = parse(&["basename", "foobar", "bar"]).unwrap();
|
||||
let settings = parse(&["basename", "foobar", "bar"]);
|
||||
assert!(!settings.zero);
|
||||
assert_eq!(settings.names, vec!["foobar"]);
|
||||
assert_eq!(settings.suffix, "bar");
|
||||
@@ -52,7 +52,7 @@ fn name_and_suffix() {
|
||||
|
||||
#[test]
|
||||
fn zero_name_and_suffix() {
|
||||
let settings = parse(&["basename", "-z", "foobar", "bar"]).unwrap();
|
||||
let settings = parse(&["basename", "-z", "foobar", "bar"]);
|
||||
assert!(settings.zero);
|
||||
assert_eq!(settings.names, vec!["foobar"]);
|
||||
assert_eq!(settings.suffix, "bar");
|
||||
@@ -60,7 +60,7 @@ fn zero_name_and_suffix() {
|
||||
|
||||
#[test]
|
||||
fn all_and_names() {
|
||||
let settings = parse(&["basename", "-a", "foobar", "bar"]).unwrap();
|
||||
let settings = parse(&["basename", "-a", "foobar", "bar"]);
|
||||
assert!(settings.multiple);
|
||||
assert!(!settings.zero);
|
||||
assert_eq!(settings.names, vec!["foobar", "bar"]);
|
||||
@@ -69,7 +69,7 @@ fn all_and_names() {
|
||||
|
||||
#[test]
|
||||
fn option_like_names() {
|
||||
let settings = parse(&["basename", "-a", "--", "-a", "-z", "--suffix=SUFFIX"]).unwrap();
|
||||
let settings = parse(&["basename", "-a", "--", "-a", "-z", "--suffix=SUFFIX"]);
|
||||
assert!(settings.multiple);
|
||||
assert!(!settings.zero);
|
||||
assert_eq!(settings.names, vec!["-a", "-z", "--suffix=SUFFIX"]);
|
||||
|
||||
@@ -78,27 +78,27 @@ struct Settings {
|
||||
|
||||
#[test]
|
||||
fn show() {
|
||||
let s = Settings::parse(["cat", "-v"]).unwrap();
|
||||
let s = Settings::parse(["cat", "-v"]);
|
||||
assert!(!s.show_ends && !s.show_tabs && s.show_nonprinting);
|
||||
|
||||
let s = Settings::parse(["cat", "-E"]).unwrap();
|
||||
let s = Settings::parse(["cat", "-E"]);
|
||||
assert!(s.show_ends && !s.show_tabs && !s.show_nonprinting);
|
||||
|
||||
let s = Settings::parse(["cat", "-T"]).unwrap();
|
||||
let s = Settings::parse(["cat", "-T"]);
|
||||
assert!(!s.show_ends && s.show_tabs && !s.show_nonprinting);
|
||||
|
||||
let s = Settings::parse(["cat", "-e"]).unwrap();
|
||||
let s = Settings::parse(["cat", "-e"]);
|
||||
assert!(s.show_ends && !s.show_tabs && s.show_nonprinting);
|
||||
|
||||
let s = Settings::parse(["cat", "-t"]).unwrap();
|
||||
let s = Settings::parse(["cat", "-t"]);
|
||||
assert!(!s.show_ends && s.show_tabs && s.show_nonprinting);
|
||||
|
||||
let s = Settings::parse(["cat", "-A"]).unwrap();
|
||||
let s = Settings::parse(["cat", "-A"]);
|
||||
assert!(s.show_ends && s.show_tabs && s.show_nonprinting);
|
||||
|
||||
let s = Settings::parse(["cat", "-te"]).unwrap();
|
||||
let s = Settings::parse(["cat", "-te"]);
|
||||
assert!(s.show_ends && s.show_tabs && s.show_nonprinting);
|
||||
|
||||
let s = Settings::parse(["cat", "-vET"]).unwrap();
|
||||
let s = Settings::parse(["cat", "-vET"]);
|
||||
assert!(s.show_ends && s.show_tabs && s.show_nonprinting);
|
||||
}
|
||||
|
||||
+10
-10
@@ -55,35 +55,35 @@ struct Settings {
|
||||
|
||||
#[test]
|
||||
fn suffix() {
|
||||
let s = Settings::parse(["mktemp", "--suffix=hello"]).unwrap();
|
||||
let s = Settings::parse(["mktemp", "--suffix=hello"]);
|
||||
assert_eq!(s.suffix.unwrap(), "hello");
|
||||
|
||||
let s = Settings::parse(["mktemp", "--suffix="]).unwrap();
|
||||
let s = Settings::parse(["mktemp", "--suffix="]);
|
||||
assert_eq!(s.suffix.unwrap(), "");
|
||||
|
||||
let s = Settings::parse(["mktemp", "--suffix="]).unwrap();
|
||||
let s = Settings::parse(["mktemp", "--suffix="]);
|
||||
assert_eq!(s.suffix.unwrap(), "");
|
||||
|
||||
let s = Settings::parse(["mktemp"]).unwrap();
|
||||
let s = Settings::parse(["mktemp"]);
|
||||
assert_eq!(s.suffix, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tmpdir() {
|
||||
let s = Settings::parse(["mktemp", "--tmpdir"]).unwrap();
|
||||
let s = Settings::parse(["mktemp", "--tmpdir"]);
|
||||
assert_eq!(s.tmp_dir.unwrap(), Path::new("."));
|
||||
|
||||
let s = Settings::parse(["mktemp", "--tmpdir="]).unwrap();
|
||||
let s = Settings::parse(["mktemp", "--tmpdir="]);
|
||||
assert_eq!(s.tmp_dir.unwrap(), Path::new(""));
|
||||
|
||||
let s = Settings::parse(["mktemp", "-p", "foo"]).unwrap();
|
||||
let s = Settings::parse(["mktemp", "-p", "foo"]);
|
||||
assert_eq!(s.tmp_dir.unwrap(), Path::new("foo"));
|
||||
|
||||
let s = Settings::parse(["mktemp", "-pfoo"]).unwrap();
|
||||
let s = Settings::parse(["mktemp", "-pfoo"]);
|
||||
assert_eq!(s.tmp_dir.unwrap(), Path::new("foo"));
|
||||
|
||||
let s = Settings::parse(["mktemp", "-p", ""]).unwrap();
|
||||
let s = Settings::parse(["mktemp", "-p", ""]);
|
||||
assert_eq!(s.tmp_dir.unwrap(), Path::new(""));
|
||||
|
||||
assert!(Settings::parse(["mktemp", "-p"]).is_err());
|
||||
assert!(Settings::try_parse(["mktemp", "-p"]).is_err());
|
||||
}
|
||||
|
||||
+5
-5
@@ -16,8 +16,8 @@ fn true_default() {
|
||||
foo: bool,
|
||||
}
|
||||
|
||||
assert!(Settings::parse(["test"]).unwrap().foo);
|
||||
assert!(!Settings::parse(["test", "--foo"]).unwrap().foo);
|
||||
assert!(Settings::parse(["test"]).foo);
|
||||
assert!(!Settings::parse(["test", "--foo"]).foo);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -37,11 +37,11 @@ fn env_var_string() {
|
||||
}
|
||||
|
||||
std::env::set_var("FOO", "one");
|
||||
assert_eq!(Settings::parse(["test"]).unwrap().foo, "one");
|
||||
assert_eq!(Settings::parse(["test"]).foo, "one");
|
||||
|
||||
std::env::set_var("FOO", "two");
|
||||
assert_eq!(Settings::parse(["test"]).unwrap().foo, "two");
|
||||
assert_eq!(Settings::parse(["test"]).foo, "two");
|
||||
|
||||
std::env::remove_var("FOO");
|
||||
assert_eq!(Settings::parse(["test"]).unwrap().foo, "");
|
||||
assert_eq!(Settings::parse(["test"]).foo, "");
|
||||
}
|
||||
|
||||
+42
-93
@@ -15,7 +15,7 @@ fn one_flag() {
|
||||
foo: bool,
|
||||
}
|
||||
|
||||
let settings = Settings::parse(["test", "-f"]).unwrap();
|
||||
let settings = Settings::parse(["test", "-f"]);
|
||||
assert!(settings.foo);
|
||||
}
|
||||
|
||||
@@ -39,19 +39,16 @@ fn two_flags() {
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "-a"]).unwrap(),
|
||||
Settings::parse(["test", "-a"]),
|
||||
Settings { a: true, b: false }
|
||||
);
|
||||
assert_eq!(Settings::parse(["test"]), Settings { a: false, b: false });
|
||||
assert_eq!(
|
||||
Settings::parse::<&[&std::ffi::OsStr]>(&[]).unwrap(),
|
||||
Settings { a: false, b: false }
|
||||
);
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "-b"]).unwrap(),
|
||||
Settings::parse(["test", "-b"]),
|
||||
Settings { a: false, b: true }
|
||||
);
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "-a", "-b"]).unwrap(),
|
||||
Settings::parse(["test", "-a", "-b"]),
|
||||
Settings { a: true, b: true }
|
||||
);
|
||||
}
|
||||
@@ -71,18 +68,9 @@ fn long_and_short_flag() {
|
||||
foo: bool,
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
Settings::parse::<&[&std::ffi::OsStr]>(&[]).unwrap(),
|
||||
Settings { foo: false },
|
||||
);
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "--foo"]).unwrap(),
|
||||
Settings { foo: true },
|
||||
);
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "-f"]).unwrap(),
|
||||
Settings { foo: true },
|
||||
);
|
||||
assert_eq!(Settings::parse(["test"]), Settings { foo: false },);
|
||||
assert_eq!(Settings::parse(["test", "--foo"]), Settings { foo: true },);
|
||||
assert_eq!(Settings::parse(["test", "-f"]), Settings { foo: true },);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -100,10 +88,7 @@ fn short_alias() {
|
||||
foo: bool,
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "-b"]).unwrap(),
|
||||
Settings { foo: true },
|
||||
);
|
||||
assert_eq!(Settings::parse(["test", "-b"]), Settings { foo: true },);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -121,10 +106,7 @@ fn long_alias() {
|
||||
foo: bool,
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "--bar"]).unwrap(),
|
||||
Settings { foo: true },
|
||||
);
|
||||
assert_eq!(Settings::parse(["test", "--bar"]), Settings { foo: true },);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -156,10 +138,10 @@ fn short_and_long_alias() {
|
||||
bar: true,
|
||||
};
|
||||
|
||||
assert_eq!(Settings::parse(["test", "--bar"]).unwrap(), foo_true);
|
||||
assert_eq!(Settings::parse(["test", "-b"]).unwrap(), foo_true);
|
||||
assert_eq!(Settings::parse(["test", "--foo"]).unwrap(), bar_true);
|
||||
assert_eq!(Settings::parse(["test", "-f"]).unwrap(), bar_true);
|
||||
assert_eq!(Settings::parse(["test", "--bar"]), foo_true);
|
||||
assert_eq!(Settings::parse(["test", "-b"]), foo_true);
|
||||
assert_eq!(Settings::parse(["test", "--foo"]), bar_true);
|
||||
assert_eq!(Settings::parse(["test", "-f"]), bar_true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -186,7 +168,7 @@ fn xyz_map_to_abc() {
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "-x"]).unwrap(),
|
||||
Settings::parse(["test", "-x"]),
|
||||
Settings {
|
||||
a: true,
|
||||
b: true,
|
||||
@@ -195,7 +177,7 @@ fn xyz_map_to_abc() {
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "-y"]).unwrap(),
|
||||
Settings::parse(["test", "-y"]),
|
||||
Settings {
|
||||
a: false,
|
||||
b: true,
|
||||
@@ -204,7 +186,7 @@ fn xyz_map_to_abc() {
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "-xy"]).unwrap(),
|
||||
Settings::parse(["test", "-xy"]),
|
||||
Settings {
|
||||
a: true,
|
||||
b: true,
|
||||
@@ -213,7 +195,7 @@ fn xyz_map_to_abc() {
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "-z"]).unwrap(),
|
||||
Settings::parse(["test", "-z"]),
|
||||
Settings {
|
||||
a: true,
|
||||
b: true,
|
||||
@@ -242,7 +224,7 @@ fn non_rust_ident() {
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "--foo-bar", "--super"]).unwrap(),
|
||||
Settings::parse(["test", "--foo-bar", "--super"]),
|
||||
Settings { a: true, b: true }
|
||||
)
|
||||
}
|
||||
@@ -261,10 +243,7 @@ fn number_flag() {
|
||||
one: bool,
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "-1"]).unwrap(),
|
||||
Settings { one: true }
|
||||
)
|
||||
assert_eq!(Settings::parse(["test", "-1"]), Settings { one: true })
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -287,28 +266,16 @@ fn false_bool() {
|
||||
foo: bool,
|
||||
}
|
||||
|
||||
assert_eq!(Settings::parse(["test", "-a"]), Settings { foo: true });
|
||||
assert_eq!(Settings::parse(["test", "-b"]), Settings { foo: false });
|
||||
assert_eq!(Settings::parse(["test", "-ab"]), Settings { foo: false });
|
||||
assert_eq!(Settings::parse(["test", "-ba"]), Settings { foo: true });
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "-a"]).unwrap(),
|
||||
Settings { foo: true }
|
||||
);
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "-b"]).unwrap(),
|
||||
Settings::parse(["test", "-a", "-b"]),
|
||||
Settings { foo: false }
|
||||
);
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "-ab"]).unwrap(),
|
||||
Settings { foo: false }
|
||||
);
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "-ba"]).unwrap(),
|
||||
Settings { foo: true }
|
||||
);
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "-a", "-b"]).unwrap(),
|
||||
Settings { foo: false }
|
||||
);
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "-b", "-a"]).unwrap(),
|
||||
Settings::parse(["test", "-b", "-a"]),
|
||||
Settings { foo: true }
|
||||
);
|
||||
|
||||
@@ -322,28 +289,16 @@ fn false_bool() {
|
||||
foo: bool,
|
||||
}
|
||||
|
||||
assert_eq!(Settings2::parse(["test", "-a"]), Settings2 { foo: true });
|
||||
assert_eq!(Settings2::parse(["test", "-b"]), Settings2 { foo: false });
|
||||
assert_eq!(Settings2::parse(["test", "-ab"]), Settings2 { foo: false });
|
||||
assert_eq!(Settings2::parse(["test", "-ba"]), Settings2 { foo: true });
|
||||
assert_eq!(
|
||||
Settings2::parse(["test", "-a"]).unwrap(),
|
||||
Settings2 { foo: true }
|
||||
);
|
||||
assert_eq!(
|
||||
Settings2::parse(["test", "-b"]).unwrap(),
|
||||
Settings2::parse(["test", "-a", "-b"]),
|
||||
Settings2 { foo: false }
|
||||
);
|
||||
assert_eq!(
|
||||
Settings2::parse(["test", "-ab"]).unwrap(),
|
||||
Settings2 { foo: false }
|
||||
);
|
||||
assert_eq!(
|
||||
Settings2::parse(["test", "-ba"]).unwrap(),
|
||||
Settings2 { foo: true }
|
||||
);
|
||||
assert_eq!(
|
||||
Settings2::parse(["test", "-a", "-b"]).unwrap(),
|
||||
Settings2 { foo: false }
|
||||
);
|
||||
assert_eq!(
|
||||
Settings2::parse(["test", "-b", "-a"]).unwrap(),
|
||||
Settings2::parse(["test", "-b", "-a"]),
|
||||
Settings2 { foo: true }
|
||||
);
|
||||
}
|
||||
@@ -379,17 +334,11 @@ fn enum_flag() {
|
||||
foo: SomeEnum,
|
||||
}
|
||||
|
||||
assert_eq!(Settings::parse(&[] as &[&str]).unwrap().foo, SomeEnum::Foo);
|
||||
assert_eq!(Settings::parse(&[] as &[&str]).foo, SomeEnum::Foo);
|
||||
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "--bar"]).unwrap().foo,
|
||||
SomeEnum::Bar
|
||||
);
|
||||
assert_eq!(Settings::parse(["test", "--bar"]).foo, SomeEnum::Bar);
|
||||
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "--baz"]).unwrap().foo,
|
||||
SomeEnum::Baz,
|
||||
);
|
||||
assert_eq!(Settings::parse(["test", "--baz"]).foo, SomeEnum::Baz,);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -407,9 +356,9 @@ fn count() {
|
||||
verbosity: u8,
|
||||
}
|
||||
|
||||
assert_eq!(Settings::parse(["test", "-v"]).unwrap().verbosity, 1);
|
||||
assert_eq!(Settings::parse(["test", "-vv"]).unwrap().verbosity, 2);
|
||||
assert_eq!(Settings::parse(["test", "-vvv"]).unwrap().verbosity, 3);
|
||||
assert_eq!(Settings::parse(["test", "-v"]).verbosity, 1);
|
||||
assert_eq!(Settings::parse(["test", "-vv"]).verbosity, 2);
|
||||
assert_eq!(Settings::parse(["test", "-vvv"]).verbosity, 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -437,8 +386,8 @@ fn infer_long_args() {
|
||||
author: bool,
|
||||
}
|
||||
|
||||
assert!(Settings::parse(["test", "--all"]).unwrap().all);
|
||||
assert!(Settings::parse(["test", "--alm"]).unwrap().almost_all);
|
||||
assert!(Settings::parse(["test", "--au"]).unwrap().author);
|
||||
assert!(Settings::parse(["test", "--a"]).is_err());
|
||||
assert!(Settings::parse(["test", "--all"]).all);
|
||||
assert!(Settings::parse(["test", "--alm"]).almost_all);
|
||||
assert!(Settings::parse(["test", "--au"]).author);
|
||||
assert!(Settings::try_parse(["test", "--a"]).is_err());
|
||||
}
|
||||
|
||||
+35
-57
@@ -18,9 +18,7 @@ fn string_option() {
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "--message=hello"])
|
||||
.unwrap()
|
||||
.message,
|
||||
Settings::parse(["test", "--message=hello"]).message,
|
||||
"hello"
|
||||
);
|
||||
}
|
||||
@@ -52,12 +50,12 @@ fn enum_option() {
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "--format=bar"]).unwrap().format,
|
||||
Settings::parse(["test", "--format=bar"]).format,
|
||||
Format::Bar
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "--format", "baz"]).unwrap().format,
|
||||
Settings::parse(["test", "--format", "baz"]).format,
|
||||
Format::Baz
|
||||
);
|
||||
}
|
||||
@@ -87,11 +85,11 @@ fn enum_option_with_fields() {
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "-i=thin"]).unwrap().indent,
|
||||
Settings::parse(["test", "-i=thin"]).indent,
|
||||
Indent::Spaces(4)
|
||||
);
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "-i=wide"]).unwrap().indent,
|
||||
Settings::parse(["test", "-i=wide"]).indent,
|
||||
Indent::Spaces(8)
|
||||
);
|
||||
}
|
||||
@@ -135,14 +133,8 @@ fn enum_with_complex_from_value() {
|
||||
indent: Indent,
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "-i=tabs"]).unwrap().indent,
|
||||
Indent::Tabs
|
||||
);
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "-i=4"]).unwrap().indent,
|
||||
Indent::Spaces(4)
|
||||
);
|
||||
assert_eq!(Settings::parse(["test", "-i=tabs"]).indent, Indent::Tabs);
|
||||
assert_eq!(Settings::parse(["test", "-i=4"]).indent, Indent::Spaces(4));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -175,29 +167,20 @@ fn color() {
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "--color=yes"]).unwrap().color,
|
||||
Settings::parse(["test", "--color=yes"]).color,
|
||||
Color::Always
|
||||
);
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "--color=always"]).unwrap().color,
|
||||
Settings::parse(["test", "--color=always"]).color,
|
||||
Color::Always
|
||||
);
|
||||
assert_eq!(Settings::parse(["test", "--color=no"]).color, Color::Never);
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "--color=no"]).unwrap().color,
|
||||
Settings::parse(["test", "--color=never"]).color,
|
||||
Color::Never
|
||||
);
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "--color=never"]).unwrap().color,
|
||||
Color::Never
|
||||
);
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "--color=auto"]).unwrap().color,
|
||||
Color::Auto
|
||||
);
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "--color"]).unwrap().color,
|
||||
Color::Always
|
||||
)
|
||||
assert_eq!(Settings::parse(["test", "--color=auto"]).color, Color::Auto);
|
||||
assert_eq!(Settings::parse(["test", "--color"]).color, Color::Always)
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -232,7 +215,7 @@ fn actions() {
|
||||
messages: Vec<String>,
|
||||
}
|
||||
|
||||
let settings = Settings::parse(["test", "-m=Hello", "-m=World", "--send"]).unwrap();
|
||||
let settings = Settings::parse(["test", "-m=Hello", "-m=World", "--send"]);
|
||||
assert_eq!(settings.messages, vec!["Hello", "World"]);
|
||||
assert_eq!(settings.message1, "World");
|
||||
assert_eq!(settings.message2, "World");
|
||||
@@ -257,8 +240,8 @@ fn width() {
|
||||
width: Option<u64>,
|
||||
}
|
||||
|
||||
assert_eq!(Settings::parse(["test", "-w=0"]).unwrap().width, None);
|
||||
assert_eq!(Settings::parse(["test", "-w=1"]).unwrap().width, Some(1));
|
||||
assert_eq!(Settings::parse(["test", "-w=0"]).width, None);
|
||||
assert_eq!(Settings::parse(["test", "-w=1"]).width, Some(1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -305,17 +288,17 @@ fn integers() {
|
||||
n: i128,
|
||||
}
|
||||
|
||||
assert_eq!(Settings::parse(["test", "--u8=5"]).unwrap().n, 5);
|
||||
assert_eq!(Settings::parse(["test", "--u16=5"]).unwrap().n, 5);
|
||||
assert_eq!(Settings::parse(["test", "--u32=5"]).unwrap().n, 5);
|
||||
assert_eq!(Settings::parse(["test", "--u64=5"]).unwrap().n, 5);
|
||||
assert_eq!(Settings::parse(["test", "--u128=5"]).unwrap().n, 5);
|
||||
assert_eq!(Settings::parse(["test", "--u8=5"]).n, 5);
|
||||
assert_eq!(Settings::parse(["test", "--u16=5"]).n, 5);
|
||||
assert_eq!(Settings::parse(["test", "--u32=5"]).n, 5);
|
||||
assert_eq!(Settings::parse(["test", "--u64=5"]).n, 5);
|
||||
assert_eq!(Settings::parse(["test", "--u128=5"]).n, 5);
|
||||
|
||||
assert_eq!(Settings::parse(["test", "--i8=5"]).unwrap().n, 5);
|
||||
assert_eq!(Settings::parse(["test", "--i16=5"]).unwrap().n, 5);
|
||||
assert_eq!(Settings::parse(["test", "--i32=5"]).unwrap().n, 5);
|
||||
assert_eq!(Settings::parse(["test", "--i64=5"]).unwrap().n, 5);
|
||||
assert_eq!(Settings::parse(["test", "--i128=5"]).unwrap().n, 5);
|
||||
assert_eq!(Settings::parse(["test", "--i8=5"]).n, 5);
|
||||
assert_eq!(Settings::parse(["test", "--i16=5"]).n, 5);
|
||||
assert_eq!(Settings::parse(["test", "--i32=5"]).n, 5);
|
||||
assert_eq!(Settings::parse(["test", "--i64=5"]).n, 5);
|
||||
assert_eq!(Settings::parse(["test", "--i128=5"]).n, 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -347,22 +330,17 @@ fn ls_classify() {
|
||||
classify: When,
|
||||
}
|
||||
|
||||
assert_eq!(Settings::parse(["test"]).unwrap().classify, When::Auto);
|
||||
assert_eq!(Settings::parse(["test"]).classify, When::Auto);
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "--classify=never"])
|
||||
.unwrap()
|
||||
.classify,
|
||||
Settings::parse(["test", "--classify=never"]).classify,
|
||||
When::Never,
|
||||
);
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "--classify"]).unwrap().classify,
|
||||
Settings::parse(["test", "--classify"]).classify,
|
||||
When::Always,
|
||||
);
|
||||
assert_eq!(
|
||||
Settings::parse(["test", "-F"]).unwrap().classify,
|
||||
When::Always,
|
||||
);
|
||||
assert!(Settings::parse(["test", "-Falways"]).is_err());
|
||||
assert_eq!(Settings::parse(["test", "-F"]).classify, When::Always,);
|
||||
assert!(Settings::try_parse(["test", "-Falways"]).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -383,16 +361,16 @@ fn mktemp_tmpdir() {
|
||||
tmpdir: Option<String>,
|
||||
}
|
||||
|
||||
let settings = Settings::parse(["test", "-p", "X"]).unwrap();
|
||||
let settings = Settings::parse(["test", "-p", "X"]);
|
||||
assert_eq!(settings.tmpdir.unwrap(), "X");
|
||||
|
||||
let settings = Settings::parse(["test", "--tmpdir=X"]).unwrap();
|
||||
let settings = Settings::parse(["test", "--tmpdir=X"]);
|
||||
assert_eq!(settings.tmpdir.unwrap(), "X");
|
||||
|
||||
let settings = Settings::parse(["test", "--tmpdir"]).unwrap();
|
||||
let settings = Settings::parse(["test", "--tmpdir"]);
|
||||
assert_eq!(settings.tmpdir.unwrap(), "/tmp");
|
||||
|
||||
assert!(Settings::parse(["test", "-p"]).is_err());
|
||||
assert!(Settings::try_parse(["test", "-p"]).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
+11
-11
@@ -15,10 +15,10 @@ fn one_positional() {
|
||||
file1: String,
|
||||
}
|
||||
|
||||
let settings = Settings::parse(["test", "foo"]).unwrap();
|
||||
let settings = Settings::parse(["test", "foo"]);
|
||||
assert_eq!(settings.file1, "foo");
|
||||
|
||||
assert!(Settings::parse(["test"]).is_err());
|
||||
assert!(Settings::try_parse(["test"]).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -40,11 +40,11 @@ fn two_positionals() {
|
||||
bar: String,
|
||||
}
|
||||
|
||||
let settings = Settings::parse(["test", "a", "b"]).unwrap();
|
||||
let settings = Settings::parse(["test", "a", "b"]);
|
||||
assert_eq!(settings.foo, "a");
|
||||
assert_eq!(settings.bar, "b");
|
||||
|
||||
assert!(Settings::parse(["test"]).is_err());
|
||||
assert!(Settings::try_parse(["test"]).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -62,9 +62,9 @@ fn optional_positional() {
|
||||
foo: Option<String>,
|
||||
}
|
||||
|
||||
let settings = Settings::parse(["test"]).unwrap();
|
||||
let settings = Settings::parse(["test"]);
|
||||
assert_eq!(settings.foo, None);
|
||||
let settings = Settings::parse(["test", "bar"]).unwrap();
|
||||
let settings = Settings::parse(["test", "bar"]);
|
||||
assert_eq!(settings.foo.unwrap(), "bar");
|
||||
}
|
||||
|
||||
@@ -83,9 +83,9 @@ fn collect_positional() {
|
||||
foo: Vec<String>,
|
||||
}
|
||||
|
||||
let settings = Settings::parse(["test", "a", "b", "c"]).unwrap();
|
||||
let settings = Settings::parse(["test", "a", "b", "c"]);
|
||||
assert_eq!(settings.foo, vec!["a", "b", "c"]);
|
||||
let settings = Settings::parse(["test"]).unwrap();
|
||||
let settings = Settings::parse(["test"]);
|
||||
assert_eq!(settings.foo, Vec::<String>::new());
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ fn last1() {
|
||||
foo: Vec<String>,
|
||||
}
|
||||
|
||||
let settings = Settings::parse(["test", "a", "-b", "c"]).unwrap();
|
||||
let settings = Settings::parse(["test", "a", "-b", "c"]);
|
||||
assert_eq!(settings.foo, vec!["a", "-b", "c"]);
|
||||
}
|
||||
|
||||
@@ -126,9 +126,9 @@ fn last2() {
|
||||
foo: Vec<String>,
|
||||
}
|
||||
|
||||
let settings = Settings::parse(["test", "-a"]).unwrap();
|
||||
let settings = Settings::parse(["test", "-a"]);
|
||||
assert_eq!(settings.foo, Vec::<String>::new());
|
||||
|
||||
let settings = Settings::parse(["test", "--", "-a"]).unwrap();
|
||||
let settings = Settings::parse(["test", "--", "-a"]);
|
||||
assert_eq!(settings.foo, vec!["-a"]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user