bpaf 0.9.25

A simple Command Line Argument Parser with parser combinators
Documentation
<details><summary>Combinatoric example</summary>

```no_run
#[derive(Debug, Clone)]
pub struct Options {
    exec: Option<Vec<OsString>>,
    switch: bool,
}

fn exec() -> impl Parser<Option<Vec<OsString>>> {
    // this defines starting token - "--exec"
    let start = long("exec")
        .help("Spawn a process for each file found")
        .req_flag(());
    // this consumes everything that is not ";"
    let body = any("COMMAND", |s| (s != ";").then_some(s))
        .help("Command and arguments, {} will be replaced with a file name")
        .some("You need to pass some arguments to exec");
    // this defines endint goken - ";"
    let end = literal(";");
    // this consumes everything between starting token and ending token
    construct!(start, body, end)
        // this makes it so everything between those tokens is consumed
        .adjacent()
        // drop the surrounding tokens leaving just the arguments
        .map(|x| x.1)
        // and make it optional so that instead of an empty Vec
        // it is `None` when no `--exec` flags was passed.
        .optional()
}

pub fn options() -> OptionParser<Options> {
    let switch = short('s')
        .long("switch")
        .help("Regular top level switch")
        .switch();
    construct!(Options { exec(), switch }).to_options()
}

fn main() {
    println!("{:?}", options().run())
}
```

</details>
<details><summary>Derive example</summary>

```no_run
#[derive(Debug, Clone, Bpaf)]
#[bpaf(options)]
pub struct Options {
    #[bpaf(external(execs))]
    exec: Option<Vec<OsString>>,
    #[bpaf(long, short)]
    /// Regular top level switch
    switch: bool,
}

#[derive(Debug, Clone, Bpaf)]
#[bpaf(adjacent)]
struct Exec {
    /// Spawn a process for each file found
    exec: (),

    #[bpaf(
        any("COMMAND", not_semi),
        some("Command and arguments, {} will be replaced with a file name")
    )]
    /// Command and arguments, {} will be replaced with a file name
    body: Vec<OsString>,

    #[bpaf(external(is_semi))]
    end: (),
}

fn not_semi(s: OsString) -> Option<OsString> {
    (s != ";").then_some(s)
}

fn is_semi() -> impl Parser<()> {
    // TODO - support literal in bpaf_derive
    literal(";")
}

// a different alternative would be to put a singular Exec
fn execs() -> impl Parser<Option<Vec<OsString>>> {
    exec().map(|e| e.body).optional()
}

fn main() {
    println!("{:?}", options().run())
}
```

</details>
<details><summary>Output</summary>

Generated `--help` message is somewhat descriptive of the purpose


<div class='bpaf-doc'>
$ app --help<br>
<p><b>Usage</b>: <tt><b>app</b></tt> [<tt><b>--exec</b></tt> <tt><i>COMMAND</i></tt>... <tt><b>;</b></tt>] [<tt><b>-s</b></tt>]</p><p><div>
<b>Available options:</b></div><dl><div style='padding-left: 0.5em'><tt><b>--exec</b></tt> <tt><i>COMMAND</i></tt>... <tt><b>;</b></tt></div><dt><tt><b>    --exec</b></tt></dt>
<dd>Spawn a process for each file found</dd>
<dt><tt><i>COMMAND</i></tt></dt>
<dd>Command and arguments, {} will be replaced with a file name</dd>
<p></p><dt><tt><b>-s</b></tt>, <tt><b>--switch</b></tt></dt>
<dd>Regular top level switch</dd>
<dt><tt><b>-h</b></tt>, <tt><b>--help</b></tt></dt>
<dd>Prints help information</dd>
</dl>
</p>
<style>
div.bpaf-doc {
    padding: 14px;
    background-color:var(--code-block-background-color);
    font-family: "Source Code Pro", monospace;
    margin-bottom: 0.75em;
}
div.bpaf-doc dt { margin-left: 1em; }
div.bpaf-doc dd { margin-left: 3em; }
div.bpaf-doc dl { margin-top: 0; padding-left: 1em; }
div.bpaf-doc  { padding-left: 1em; }
</style>
</div>


You can have as many items between `--exec` and `;` as you want, they all will be captured
inside the exec vector. Extra options can go either before or after the block.


<div class='bpaf-doc'>
$ app --exec foo --bar ; -s<br>
Options { exec: Some(["foo", "--bar"]), switch: true }
</div>


This example uses [`some`](Parser::some) to make sure there are some parameters, but that's
optional.


<div class='bpaf-doc'>
$ app --exec ;<br>
<b>Error:</b> <b>--exec</b> is not expected in this context
<style>
div.bpaf-doc {
    padding: 14px;
    background-color:var(--code-block-background-color);
    font-family: "Source Code Pro", monospace;
    margin-bottom: 0.75em;
}
div.bpaf-doc dt { margin-left: 1em; }
div.bpaf-doc dd { margin-left: 3em; }
div.bpaf-doc dl { margin-top: 0; padding-left: 1em; }
div.bpaf-doc  { padding-left: 1em; }
</style>
</div>

</details>