-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4080 from epage/iter
feat(parser): Report what arg ids are present
- Loading branch information
Showing
11 changed files
with
357 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
`find` is an example of position-sensitive flags | ||
|
||
```console | ||
$ find --help | ||
clap 4.0.0-alpha.0 | ||
A simple to use, efficient, and full-featured Command Line Argument Parser | ||
|
||
USAGE: | ||
find[EXE] [OPTIONS] --name <NAME> | ||
|
||
OPTIONS: | ||
-h, --help Print help information | ||
-V, --version Print version information | ||
|
||
TESTS: | ||
--empty File is empty and is either a regular file or a directory | ||
--name <NAME> Base of file name (the path with the leading directories removed) matches | ||
shell pattern pattern | ||
|
||
OPERATORS: | ||
-o, --or expr2 is not evaluate if exp1 is true | ||
-a, --and Same as `expr1 expr1` | ||
|
||
$ find --empty -o --name .keep | ||
[ | ||
( | ||
"empty", | ||
Bool( | ||
true, | ||
), | ||
), | ||
( | ||
"or", | ||
Bool( | ||
true, | ||
), | ||
), | ||
( | ||
"name", | ||
String( | ||
".keep", | ||
), | ||
), | ||
] | ||
|
||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
use std::collections::BTreeMap; | ||
|
||
use clap::{arg, command, ArgGroup, ArgMatches, Command}; | ||
|
||
fn main() { | ||
let matches = cli().get_matches(); | ||
let values = Value::from_matches(&matches); | ||
println!("{:#?}", values); | ||
} | ||
|
||
fn cli() -> Command<'static> { | ||
command!() | ||
.group(ArgGroup::new("tests").multiple(true)) | ||
.next_help_heading("TESTS") | ||
.args([ | ||
arg!(--empty "File is empty and is either a regular file or a directory").group("tests"), | ||
arg!(--name <NAME> "Base of file name (the path with the leading directories removed) matches shell pattern pattern").group("tests"), | ||
]) | ||
.group(ArgGroup::new("operators").multiple(true)) | ||
.next_help_heading("OPERATORS") | ||
.args([ | ||
arg!(-o - -or "expr2 is not evaluate if exp1 is true").group("operators"), | ||
arg!(-a - -and "Same as `expr1 expr1`").group("operators"), | ||
]) | ||
} | ||
|
||
#[derive(Clone, PartialEq, Eq, Hash, Debug)] | ||
pub enum Value { | ||
Bool(bool), | ||
String(String), | ||
} | ||
|
||
impl Value { | ||
pub fn from_matches(matches: &ArgMatches) -> Vec<(clap::Id, Self)> { | ||
let mut values = BTreeMap::new(); | ||
for id in matches.ids() { | ||
if matches.try_get_many::<clap::Id>(id.as_str()).is_ok() { | ||
// ignore groups | ||
continue; | ||
} | ||
let value_source = matches | ||
.value_source(id.as_str()) | ||
.expect("id came from matches"); | ||
if value_source != clap::parser::ValueSource::CommandLine { | ||
// Any other source just gets tacked on at the end (like default values) | ||
continue; | ||
} | ||
if Self::extract::<String>(matches, id, &mut values) { | ||
continue; | ||
} | ||
if Self::extract::<bool>(matches, id, &mut values) { | ||
continue; | ||
} | ||
unimplemented!("unknown type for {}: {:?}", id, matches); | ||
} | ||
values.into_values().collect::<Vec<_>>() | ||
} | ||
|
||
fn extract<T: Clone + Into<Value> + Send + Sync + 'static>( | ||
matches: &ArgMatches, | ||
id: &clap::Id, | ||
output: &mut BTreeMap<usize, (clap::Id, Self)>, | ||
) -> bool { | ||
match matches.try_get_many::<T>(id.as_str()) { | ||
Ok(Some(values)) => { | ||
for (value, index) in values.zip( | ||
matches | ||
.indices_of(id.as_str()) | ||
.expect("id came from matches"), | ||
) { | ||
output.insert(index, (id.clone(), value.clone().into())); | ||
} | ||
true | ||
} | ||
Ok(None) => { | ||
unreachable!("`ids` only reports what is present") | ||
} | ||
Err(clap::parser::MatchesError::UnknownArgument { .. }) => { | ||
unreachable!("id came from matches") | ||
} | ||
Err(clap::parser::MatchesError::Downcast { .. }) => false, | ||
Err(_) => { | ||
unreachable!("id came from matches") | ||
} | ||
} | ||
} | ||
} | ||
|
||
impl From<String> for Value { | ||
fn from(other: String) -> Self { | ||
Self::String(other) | ||
} | ||
} | ||
|
||
impl From<bool> for Value { | ||
fn from(other: bool) -> Self { | ||
Self::Bool(other) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
//! # Example: find-like CLI (Builder API) | ||
//! | ||
//! ```rust | ||
#![doc = include_str!("../../examples/find.rs")] | ||
//! ``` | ||
//! | ||
#![doc = include_str!("../../examples/find.md")] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.