Skip to content

Commit

Permalink
fix(macros): Allow dashed values (#3699)
Browse files Browse the repository at this point in the history
add support for dashed arg names and values in arg! macro
  • Loading branch information
evgeniy-terekhin committed May 6, 2022
1 parent 95698a4 commit 229b44d
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 0 deletions.
56 changes: 56 additions & 0 deletions src/macros.rs
Expand Up @@ -512,6 +512,32 @@ macro_rules! arg_impl {
$($tail)*
}
};
(
@arg
($arg:expr)
<$value_name:literal>
$($tail:tt)*
) => {
$crate::arg_impl! {
@arg
({
debug_assert!(!$arg.is_multiple_occurrences_set(), "Values should precede `...`");
debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported");

let mut arg = $arg;

arg = arg.required(true);
arg = arg.takes_value(true);

let value_name = $crate::arg_impl! { @string $value_name };
if arg.get_id().is_empty() {
arg = arg.id(value_name);
}
arg.value_name(value_name)
})
$($tail)*
}
};
(
@arg
($arg:expr)
Expand Down Expand Up @@ -542,6 +568,36 @@ macro_rules! arg_impl {
$($tail)*
}
};
(
@arg
($arg:expr)
[$value_name:literal]
$($tail:tt)*
) => {
$crate::arg_impl! {
@arg
({
debug_assert!(!$arg.is_multiple_occurrences_set(), "Values should precede `...`");
debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported");

let mut arg = $arg;

if arg.get_long().is_none() && arg.get_short().is_none() {
arg = arg.required(false);
} else {
arg = arg.min_values(0).max_values(1);
}
arg = arg.takes_value(true);

let value_name = $crate::arg_impl! { @string $value_name };
if arg.get_id().is_empty() {
arg = arg.id(value_name);
}
arg.value_name(value_name)
})
$($tail)*
}
};
(
@arg
($arg:expr)
Expand Down
56 changes: 56 additions & 0 deletions tests/macros.rs
Expand Up @@ -469,4 +469,60 @@ mod arg_impl {
let actual = clap::arg_impl! { @char 'o' };
assert_eq!(actual, expected);
}

#[test]
// allow double quoted dashed arg name in square brackets (e.g ["some-arg"])
fn arg_name_dashed() {
let arg = clap::arg!(["some-arg"] "some arg");
assert_eq!(arg, clap::Arg::new("some-arg").help("some arg"));

let m = clap::Command::new("flag")
.arg(arg)
.try_get_matches_from(vec!["", "some-val"])
.unwrap();
assert!(m.is_present("some-arg"));
assert_eq!(m.value_of("some-arg").unwrap(), "some-val");
}

#[test]
// allow double quoted dashed arg value in triangle brackets (e.g <"some-val">)
// test in combination with short argument name (e.g. -v)
fn arg_value_dashed_with_short_arg() {
let arg = clap::arg!(-a <"some-val"> "some arg");
assert_eq!(
arg,
clap::Arg::new("some-val")
.short('a')
.long("arg")
.value_name("some-val")
);

let m = clap::Command::new("cmd")
.arg(arg)
.try_get_matches_from(vec!["", "-a", "val"])
.unwrap();
assert!(m.is_present("some-val"));
assert_eq!(m.value_of("some-val").unwrap(), "val");
}

#[test]
// allow double quoted dashed arg value in triangle brackets (e.g <"some-val">)
// test in combination with long argument name (e.g. --value)
fn arg_value_dashed_with_long_arg() {
let arg = clap::arg!(-a --arg <"some-val"> "some arg");
assert_eq!(
arg,
clap::Arg::new("arg")
.short('a')
.long("arg")
.value_name("some-val")
);

let m = clap::Command::new("cmd")
.arg(arg)
.try_get_matches_from(vec!["", "--arg", "some-val"])
.unwrap();
assert!(m.is_present("arg"));
assert_eq!(m.value_of("arg").unwrap(), "some-val");
}
}

0 comments on commit 229b44d

Please sign in to comment.