Skip to content

Commit 36cf5df

Browse files
committed
Add support for optional argument/flag with optional value
TakesValue::Optional introduced which allows for an optional flag with an optional value (equivalent to getopts' optflagopt mode). Can be used where a default value for a modifier could exist, but the user might prefer to override. Will be used to implement #284, permitting --time to default to "sort by modification date" for compatibility with GNU/posix ls but keeping support for exa's previous behavior.
1 parent aa2e3a5 commit 36cf5df

File tree

1 file changed

+25
-5
lines changed

1 file changed

+25
-5
lines changed

src/options/parser.rs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ pub enum TakesValue {
9292

9393
/// This flag will throw an error if there’s a value after it.
9494
Forbidden,
95+
96+
/// This flag may be followed by a value to override its defaults
97+
Optional,
9598
}
9699

97100

@@ -171,7 +174,7 @@ impl Args {
171174
let arg = self.lookup_long(before)?;
172175
let flag = Flag::Long(arg.long);
173176
match arg.takes_value {
174-
Necessary => result_flags.push((flag, Some(after))),
177+
Necessary|Optional => result_flags.push((flag, Some(after))),
175178
Forbidden => return Err(ParseError::ForbiddenValue { flag })
176179
}
177180
}
@@ -190,6 +193,14 @@ impl Args {
190193
else {
191194
return Err(ParseError::NeedsValue { flag })
192195
}
196+
},
197+
Optional => {
198+
if let Some(next_arg) = inputs.next() {
199+
result_flags.push((flag, Some(next_arg)));
200+
}
201+
else {
202+
result_flags.push((flag, None));
203+
}
193204
}
194205
}
195206
}
@@ -220,7 +231,7 @@ impl Args {
220231
let arg = self.lookup_short(*byte)?;
221232
let flag = Flag::Short(*byte);
222233
match arg.takes_value {
223-
Forbidden => result_flags.push((flag, None)),
234+
Forbidden|Optional => result_flags.push((flag, None)),
224235
Necessary => return Err(ParseError::NeedsValue { flag })
225236
}
226237
}
@@ -229,7 +240,7 @@ impl Args {
229240
let arg = self.lookup_short(*arg_with_value)?;
230241
let flag = Flag::Short(arg.short.unwrap());
231242
match arg.takes_value {
232-
Necessary => result_flags.push((flag, Some(after))),
243+
Necessary|Optional => result_flags.push((flag, Some(after))),
233244
Forbidden => return Err(ParseError::ForbiddenValue { flag })
234245
}
235246
}
@@ -252,7 +263,7 @@ impl Args {
252263
let flag = Flag::Short(*byte);
253264
match arg.takes_value {
254265
Forbidden => result_flags.push((flag, None)),
255-
Necessary => {
266+
Necessary|Optional => {
256267
if index < bytes.len() - 1 {
257268
let remnants = &bytes[index+1 ..];
258269
result_flags.push((flag, Some(OsStr::from_bytes(remnants))));
@@ -262,8 +273,17 @@ impl Args {
262273
result_flags.push((flag, Some(next_arg)));
263274
}
264275
else {
265-
return Err(ParseError::NeedsValue { flag })
276+
match arg.takes_value {
277+
Forbidden => assert!(false),
278+
Necessary => {
279+
return Err(ParseError::NeedsValue { flag });
280+
},
281+
Optional => {
282+
result_flags.push((flag, None));
283+
}
284+
}
266285
}
286+
267287
}
268288
}
269289
}

0 commit comments

Comments
 (0)