Skip to content

Commit 7321195

Browse files
committed
feat(Defult Values): adds support for default values in args
Closes #418
1 parent e76d751 commit 7321195

File tree

4 files changed

+56
-8
lines changed

4 files changed

+56
-8
lines changed

src/app/parser.rs

+19
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,7 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
535535
}
536536
}
537537

538+
try!(self.add_defaults(matcher));
538539
try!(self.validate_blacklist(matcher));
539540
try!(self.validate_num_args(matcher));
540541
matcher.usage(self.create_usage(&[]));
@@ -1518,4 +1519,22 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
15181519
}
15191520
w.flush().map_err(Error::from)
15201521
}
1522+
1523+
fn add_defaults(&mut self, matcher: &mut ArgMatcher<'a>) -> ClapResult<()> {
1524+
macro_rules! add_val {
1525+
($_self:ident, $a:ident, $m:ident) => {
1526+
if $m.get($a.name).is_none() {
1527+
try!($_self.add_val_to_arg($a, OsStr::new($a.default_val.as_ref().unwrap()), $m));
1528+
arg_post_processing!($_self, $a, $m);
1529+
}
1530+
};
1531+
}
1532+
for o in self.opts.iter().filter(|o| o.default_val.is_some()) {
1533+
add_val!(self, o, matcher);
1534+
}
1535+
for p in self.positionals.values().filter(|p| p.default_val.is_some()) {
1536+
add_val!(self, p, matcher);
1537+
}
1538+
Ok(())
1539+
}
15211540
}

src/args/arg.rs

+31-8
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ pub struct Arg<'a, 'b> where 'a: 'b {
6666
pub settings: ArgFlags,
6767
#[doc(hidden)]
6868
pub val_delim: Option<char>,
69+
#[doc(hidden)]
70+
pub default_val: Option<&'a str>,
6971
}
7072

7173
impl<'a, 'b> Default for Arg<'a, 'b> {
@@ -88,6 +90,7 @@ impl<'a, 'b> Default for Arg<'a, 'b> {
8890
overrides: None,
8991
settings: ArgFlags::new(),
9092
val_delim: Some(','),
93+
default_val: None,
9194
}
9295
}
9396
}
@@ -1087,14 +1090,23 @@ impl<'a, 'b> Arg<'a, 'b> {
10871090
self
10881091
}
10891092

1090-
#[doc(hidden)]
1091-
pub fn setb(&mut self, s: ArgSettings) {
1092-
self.settings.set(s);
1093-
}
1094-
1095-
#[doc(hidden)]
1096-
pub fn unsetb(&mut self, s: ArgSettings) {
1097-
self.settings.unset(s);
1093+
/// Specifies the value of the argument when *not* used at runtime.
1094+
///
1095+
/// **NOTE:** implicitly sets `Arg::takes_value(true)`
1096+
///
1097+
/// # Examples
1098+
///
1099+
/// ```rust
1100+
/// # use clap::{App, Arg};
1101+
/// Arg::with_name("input")
1102+
/// .long("option")
1103+
/// .default_value("myval")
1104+
/// # ;
1105+
/// ```
1106+
pub fn default_value(mut self, val: &'a str) -> Self {
1107+
self.setb(ArgSettings::TakesValue);
1108+
self.default_val = Some(val);
1109+
self
10981110
}
10991111

11001112
/// Checks if one of the `ArgSettings` settings is set for the argument
@@ -1113,6 +1125,16 @@ impl<'a, 'b> Arg<'a, 'b> {
11131125
self.unsetb(s);
11141126
self
11151127
}
1128+
1129+
#[doc(hidden)]
1130+
pub fn setb(&mut self, s: ArgSettings) {
1131+
self.settings.set(s);
1132+
}
1133+
1134+
#[doc(hidden)]
1135+
pub fn unsetb(&mut self, s: ArgSettings) {
1136+
self.settings.unset(s);
1137+
}
11161138
}
11171139

11181140
impl<'a, 'b, 'z> From<&'z Arg<'a, 'b>>
@@ -1136,6 +1158,7 @@ impl<'a, 'b, 'z> From<&'z Arg<'a, 'b>>
11361158
overrides: a.overrides.clone(),
11371159
settings: a.settings.clone(),
11381160
val_delim: a.val_delim,
1161+
default_val: a.default_val,
11391162
}
11401163
}
11411164
}

src/args/arg_builder/option.rs

+3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ pub struct OptBuilder<'n, 'e> {
2626
pub overrides: Option<Vec<&'e str>>,
2727
pub settings: ArgFlags,
2828
pub val_delim: Option<char>,
29+
pub default_val: Option<&'n str>,
2930
}
3031

3132
impl<'n, 'e> Default for OptBuilder<'n, 'e> {
@@ -46,6 +47,7 @@ impl<'n, 'e> Default for OptBuilder<'n, 'e> {
4647
overrides: None,
4748
settings: ArgFlags::new(),
4849
val_delim: Some(','),
50+
default_val: None,
4951
}
5052
}
5153
}
@@ -79,6 +81,7 @@ impl<'n, 'e> OptBuilder<'n, 'e> {
7981
requires: a.requires.clone(),
8082
possible_vals: a.possible_vals.clone(),
8183
settings: a.settings.clone(),
84+
default_val: a.default_val,
8285
..Default::default()
8386
};
8487
if let Some(ref vec) = ob.val_names {

src/args/arg_builder/positional.rs

+3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ pub struct PosBuilder<'n, 'e> {
2626
pub overrides: Option<Vec<&'e str>>,
2727
pub settings: ArgFlags,
2828
pub val_delim: Option<char>,
29+
pub default_val: Option<&'n str>,
2930
}
3031

3132
impl<'n, 'e> Default for PosBuilder<'n, 'e> {
@@ -45,6 +46,7 @@ impl<'n, 'e> Default for PosBuilder<'n, 'e> {
4546
overrides: None,
4647
settings: ArgFlags::new(),
4748
val_delim: Some(','),
49+
default_val: None,
4850
}
4951
}
5052
}
@@ -80,6 +82,7 @@ impl<'n, 'e> PosBuilder<'n, 'e> {
8082
help: a.help,
8183
val_delim: a.val_delim,
8284
settings: a.settings.clone(),
85+
default_val: a.default_val,
8386
..Default::default()
8487
};
8588
if a.max_vals.is_some()

0 commit comments

Comments
 (0)