Struct bpaf::params::ParseCommand
source · pub struct ParseCommand<T> { /* private fields */ }
Expand description
Builder structure for the [command
]
Created with [command
], implements parser for the inner structure, gives access to help
.
Implementations§
source§impl<P> ParseCommand<P>
impl<P> ParseCommand<P>
sourcepub fn help<M>(self, help: M) -> Self
pub fn help<M>(self, help: M) -> Self
Add a brief description to a command
bpaf
uses this description along with the command name
in help output so it shouldn’t exceed one or two lines. If help
isn’t specified
bpaf
falls back to descr
from the inner parser.
§Combinatoric usage
fn inner() -> OptionParser<bool> {
short('i')
.help("Mysterious inner switch")
.switch()
.to_options()
.descr("performs an operation")
}
fn mysterious_parser() -> impl Parser<bool> {
inner().command("mystery")
.help("This command performs a mystery operation")
}
§Derive usage
bpaf_derive
uses doc comments for inner parser, no specific options are available.
See descr
for more details
/// This command performs a mystery operation
#[derive(Debug, Clone, Bpaf)]
#[bpaf(command)]
struct Mystery {
#[bpaf(short)]
/// Mysterious inner switch
inner: bool,
}
§Example
$ app --help
<skip>
Available commands:
mystery This command performs a mystery operation
Examples found in repository?
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
fn main() {
let bar = short('b')
.long("bar")
.help("some bar command")
.argument::<String>("BAR")
.optional();
let bar_cmd = construct!(Foo { bar })
.to_options()
.descr("This command will try to do foo given a bar argument");
let opt = bar_cmd
.command("foo")
.help("command for doing foo")
.map(Command::Foo)
.to_options()
.run();
println!("{:#?}", opt);
}
More examples
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
fn main() {
let dry_run = long("dry_run").switch();
let all = long("all").switch();
let repository = positional::<String>("SRC").fallback("origin".to_string());
let fetch = construct!(Opt::Fetch {
dry_run,
all,
repository
})
.to_options()
.descr("fetches branches from remote repository");
let fetch_cmd = fetch.command("fetch");
let interactive = short('i').switch();
let all = long("all").switch();
let files = positional::<PathBuf>("FILE").many();
let add = construct!(Opt::Add {
interactive,
all,
files
})
.to_options()
.descr("add files to the staging area");
let add_cmd = add.command("add").help("add files to the staging area");
let opt = construct!([fetch_cmd, add_cmd])
.to_options()
.descr("The stupid content tracker")
.run();
println!("{:?}", opt);
}
sourcepub fn short(self, short: char) -> Self
pub fn short(self, short: char) -> Self
Add a custom short alias for a command
Behavior is similar to short
, only first short name is visible.
sourcepub fn long(self, long: &'static str) -> Self
pub fn long(self, long: &'static str) -> Self
Add a custom hidden long alias for a command
Behavior is similar to long
, but since you had to specify the first long
name when making the command - this one becomes a hidden alias.
sourcepub fn adjacent(self) -> Self
pub fn adjacent(self) -> Self
Allow for the command to succeed even if there are non consumed items present
Normally a subcommand parser should handle the rest of the unconsumed elements thus
allowing only “vertical” chaining of commands. adjacent
modifier lets command parser to
succeed if there are leftovers for as long as all comsumed items form a single adjacent
block. This opens possibilities to chain commands sequentially.
Let’s consider two examples with consumed items marked in bold :
cmd -a -b -c -d
cmd -a -c -b -d
In the first example -b
breaks the adjacency for all the consumed items so parsing will fail,
while here in the second one the name and all the consumed items are adjacent to each other so
parsing will succeed.
Combinatoric example
#[derive(Debug, Clone)]
pub struct Options {
premium: bool,
commands: Vec<Cmd>,
}
#[derive(Debug, Clone)]
// shape of the variants doesn't really matter, let's use all of them :)
enum Cmd {
Eat(String),
Drink { coffee: bool },
Sleep { time: usize },
}
fn cmd() -> impl Parser<Cmd> {
let eat = positional::<String>("FOOD")
.to_options()
.descr("Performs eating action")
.command("eat")
.adjacent()
.map(Cmd::Eat);
let coffee = long("coffee")
.help("Are you going to drink coffee?")
.switch();
let drink = construct!(Cmd::Drink { coffee })
.to_options()
.descr("Performs drinking action")
.command("drink")
.adjacent();
let time = long("time").argument::<usize>("HOURS");
let sleep = construct!(Cmd::Sleep { time })
.to_options()
.descr("Performs taking a nap action")
.command("sleep")
.adjacent();
construct!([eat, drink, sleep])
}
pub fn options() -> OptionParser<Options> {
let premium = short('p')
.long("premium")
.help("Opt in for premium serivces")
.switch();
let commands = cmd().many();
construct!(Options { premium, commands }).to_options()
}
fn main() {
println!("{:?}", options().run())
}
Derive example
#[derive(Debug, Clone, Bpaf)]
#[bpaf(options)]
pub struct Options {
#[bpaf(short, long)]
/// Opt in for premium serivces
pub premium: bool,
#[bpaf(external(cmd), many)]
pub commands: Vec<Cmd>,
}
#[derive(Debug, Clone, Bpaf)]
pub enum Cmd {
#[bpaf(command, adjacent)]
/// Performs eating action
Eat(#[bpaf(positional("FOOD"))] String),
#[bpaf(command, adjacent)]
/// Performs drinking action
Drink {
/// Are you going to drink coffee?
coffee: bool,
},
#[bpaf(command, adjacent)]
/// Performs taking a nap action
Sleep {
#[bpaf(argument("HOURS"))]
time: usize,
},
}
fn main() {
println!("{:?}", options().run())
}
Output
Example implements a parser that supports one of three possible commands:
Usage: app [-p] [COMMAND ...]...
- -p, --premium
- Opt in for premium serivces
- -h, --help
- Prints help information
- eat
- Performs eating action
- drink
- Performs drinking action
- sleep
- Performs taking a nap action
As usual every command comes with its own help
Performs drinking action
Usage: app drink [--coffee]
- --coffee
- Are you going to drink coffee?
- -h, --help
- Prints help information
Normally you can use one command at a time, but making commands adjacent
lets
parser to succeed after consuming an adjacent block only and leaving leftovers for the rest of
the parser, consuming them as a Vec<Cmd>
with many
allows to chain multiple
items sequentially
Options { premium: false, commands: [Eat("Fastfood"), Drink { coffee: true }, Sleep { time: 5 }] }
The way this works is by running parsers for each command. In the first iteration eat
succeeds,
it consumes eat fastfood
portion and appends its value to the resulting vector. Then second
iteration runs on leftovers, in this case it will be drink --coffee sleep --time=5
.
Here drink
succeeds and consumes drink --coffee
portion, then sleep
parser runs, etc.
You can mix chained commands with regular arguments that belong to the top level parser
Options { premium: true, commands: [Sleep { time: 10 }, Eat("Bak Kut Teh"), Drink { coffee: false }] }
But not inside the command itself since values consumed by the command are not going to be adjacent
Error: expected FOOD, pass --help for usage information
Trait Implementations§
source§impl<T> Parser<T> for ParseCommand<T>
impl<T> Parser<T> for ParseCommand<T>
source§fn collect<C>(self) -> ParseCollect<Self, C, T>where
C: FromIterator<T>,
Self: Sized,
fn collect<C>(self) -> ParseCollect<Self, C, T>where
C: FromIterator<T>,
Self: Sized,
source§fn optional(self) -> ParseOptional<Self>
fn optional(self) -> ParseOptional<Self>
source§fn count(self) -> ParseCount<Self, T>
fn count(self) -> ParseCount<Self, T>
source§fn last(self) -> ParseLast<Self>
fn last(self) -> ParseLast<Self>
source§fn parse<F, R, E>(self, f: F) -> ParseWith<T, Self, F, E, R>
fn parse<F, R, E>(self, f: F) -> ParseWith<T, Self, F, E, R>
source§fn map<F, R>(self, map: F) -> ParseMap<T, Self, F, R>
fn map<F, R>(self, map: F) -> ParseMap<T, Self, F, R>
source§fn guard<F>(self, check: F, message: &'static str) -> ParseGuard<Self, F>
fn guard<F>(self, check: F, message: &'static str) -> ParseGuard<Self, F>
source§fn fallback(self, value: T) -> ParseFallback<Self, T>
fn fallback(self, value: T) -> ParseFallback<Self, T>
source§fn fallback_with<F, E>(self, fallback: F) -> ParseFallbackWith<T, Self, F, E>
fn fallback_with<F, E>(self, fallback: F) -> ParseFallbackWith<T, Self, F, E>
source§fn hide(self) -> ParseHide<Self>
fn hide(self) -> ParseHide<Self>
source§fn hide_usage(self) -> ParseUsage<Self>
fn hide_usage(self) -> ParseUsage<Self>
source§fn custom_usage<M>(self, usage: M) -> ParseUsage<Self>
fn custom_usage<M>(self, usage: M) -> ParseUsage<Self>
source§fn group_help<M: Into<Doc>>(self, message: M) -> ParseGroupHelp<Self>
fn group_help<M: Into<Doc>>(self, message: M) -> ParseGroupHelp<Self>
source§fn with_group_help<F>(self, f: F) -> ParseWithGroupHelp<Self, F>
fn with_group_help<F>(self, f: F) -> ParseWithGroupHelp<Self, F>
source§fn complete<M, F>(self, op: F) -> ParseComp<Self, F>
fn complete<M, F>(self, op: F) -> ParseComp<Self, F>
autocomplete
only.source§fn complete_shell(self, op: ShellComp) -> ParseCompShell<Self>
fn complete_shell(self, op: ShellComp) -> ParseCompShell<Self>
autocomplete
only.