summaryrefslogtreecommitdiffstats
path: root/vendor/clap/examples/derive_ref
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /vendor/clap/examples/derive_ref
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/clap/examples/derive_ref')
-rw-r--r--vendor/clap/examples/derive_ref/README.md440
-rw-r--r--vendor/clap/examples/derive_ref/augment_args.rs30
-rw-r--r--vendor/clap/examples/derive_ref/augment_subcommands.rs21
-rw-r--r--vendor/clap/examples/derive_ref/custom-bool.md47
-rw-r--r--vendor/clap/examples/derive_ref/custom-bool.rs32
-rw-r--r--vendor/clap/examples/derive_ref/flatten_hand_args.rs81
-rw-r--r--vendor/clap/examples/derive_ref/hand_subcommand.rs81
-rw-r--r--vendor/clap/examples/derive_ref/interop_tests.md256
8 files changed, 988 insertions, 0 deletions
diff --git a/vendor/clap/examples/derive_ref/README.md b/vendor/clap/examples/derive_ref/README.md
new file mode 100644
index 000000000..a3b0c084d
--- /dev/null
+++ b/vendor/clap/examples/derive_ref/README.md
@@ -0,0 +1,440 @@
+# Derive Reference
+
+1. [Overview](#overview)
+2. [Attributes](#attributes)
+ 1. [Terminology](#terminology)
+ 2. [Command Attributes](#command-attributes)
+ 3. [Arg Attributes](#arg-attributes)
+ 4. [Arg Enum Attributes](#arg-enum-attributes)
+ 5. [Possible Value Attributes](#possible-value-attributes)
+3. [Arg Types](#arg-types)
+4. [Doc Comments](#doc-comments)
+5. [Tips](#tips)
+6. [Mixing Builder and Derive APIS](#mixing-builder-and-derive-apis)
+
+## Overview
+
+To derive `clap` types, you need to enable the `derive` feature flag.
+
+See [demo.rs](../demo.rs) and [demo.md](../demo.md) for a brief example.
+
+Let's start by breaking down the anatomy of the derive attributes:
+```rust
+use clap::{Parser, Args, Subcommand, ValueEnum};
+
+/// Doc comment
+#[derive(Parser)]
+#[clap(APP ATTRIBUTE)]
+struct Cli {
+ /// Doc comment
+ #[clap(ARG ATTRIBUTE)]
+ field: UserType,
+
+ #[clap(value_enum, ARG ATTRIBUTE...)]
+ field: EnumValues,
+
+ #[clap(flatten)]
+ delegate: Struct,
+
+ #[clap(subcommand)]
+ command: Command,
+}
+
+/// Doc comment
+#[derive(Args)]
+#[clap(PARENT APP ATTRIBUTE)]
+struct Struct {
+ /// Doc comment
+ #[clap(ARG ATTRIBUTE)]
+ field: UserType,
+}
+
+/// Doc comment
+#[derive(Subcommand)]
+#[clap(PARENT APP ATTRIBUTE)]
+enum Command {
+ /// Doc comment
+ #[clap(APP ATTRIBUTE)]
+ Variant1(Struct),
+
+ /// Doc comment
+ #[clap(APP ATTRIBUTE)]
+ Variant2 {
+ /// Doc comment
+ #[clap(ARG ATTRIBUTE)]
+ field: UserType,
+ }
+}
+
+/// Doc comment
+#[derive(ValueEnum)]
+#[clap(ARG ENUM ATTRIBUTE)]
+enum EnumValues {
+ /// Doc comment
+ #[clap(POSSIBLE VALUE ATTRIBUTE)]
+ Variant1,
+}
+
+fn main() {
+ let cli = Cli::parse();
+}
+```
+
+- `Parser` parses arguments into a `struct` (arguments) or `enum` (subcommands).
+- `Args` allows defining a set of re-usable arguments that get merged into their parent container.
+- `Subcommand` defines available subcommands.
+ - Subcommand arguments can be defined in a struct-variant or automatically flattened with a tuple-variant.
+- `ValueEnum` allows parsing a value directly into an `enum`, erroring on unsupported values.
+ - The derive doesn't work on enums that contain non-unit variants, unless they are skipped
+
+See also the [tutorial](../tutorial_derive/README.md) and [examples](../README.md).
+
+## Attributes
+
+### Terminology
+
+**Raw attributes** are forwarded directly to the underlying `clap` builder. Any
+`Command`, `Arg`, or `PossibleValue` method can be used as an attribute.
+
+Raw attributes come in two different syntaxes:
+```rust
+#[clap(
+ global = true, // name = arg form, neat for one-arg methods
+ required_if_eq("out", "file") // name(arg1, arg2, ...) form.
+)]
+```
+
+- `method = arg` can only be used for methods which take only one argument.
+- `method(arg1, arg2)` can be used with any method.
+
+As long as `method_name` is not one of the magical methods - it will be
+translated into a mere method call.
+
+**Magic attributes** have post-processing done to them, whether that is
+- Providing of defaults
+- Special behavior is triggered off of it
+
+Magic attributes are more constrained in the syntax they support, usually just
+`<attr> = <value>` though some use `<attr>(<value>)` instead. See the specific
+magic attributes documentation for details. This allows users to access the
+raw behavior of an attribute via `<attr>(<value>)` syntax.
+
+**NOTE:** Some attributes are inferred from [Arg Types](#arg-types) and [Doc
+Comments](#doc-comments). Explicit attributes take precedence over inferred
+attributes.
+
+### Command Attributes
+
+These correspond to a `clap::Command` which is used for both top-level parsers and
+when defining subcommands.
+
+**Raw attributes:** Any [`Command` method](https://docs.rs/clap/latest/clap/type.Command.html) can also be used as an attribute, see [Terminology](#terminology) for syntax.
+- e.g. `#[clap(arg_required_else_help(true))]` would translate to `cmd.arg_required_else_help(true)`
+
+**Magic attributes:**
+- `name = <expr>`: `clap::Command::name`
+ - When not present: [crate `name`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-name-field) (`Parser` container), variant name (`Subcommand` variant)
+- `version [= <expr>]`: `clap::Command::version`
+ - When not present: no version set
+ - Without `<expr>`: defaults to [crate `version`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-version-field)
+- `author [= <expr>]`: `clap::Command::author`
+ - When not present: no author set
+ - Without `<expr>`: defaults to [crate `authors`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-authors-field)
+- `about [= <expr>]`: `clap::Command::about`
+ - When not present: [Doc comment summary](#doc-comments)
+ - Without `<expr>`: [crate `description`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-description-field) (`Parser` container)
+ - **TIP:** When a doc comment is also present, you most likely want to add
+ `#[clap(long_about = None)]` to clear the doc comment so only `about`
+ gets shown with both `-h` and `--help`.
+- `long_about = <expr>`: `clap::Command::long_about`
+ - When not present: [Doc comment](#doc-comments) if there is a blank line, else nothing
+- `verbatim_doc_comment`: Minimizes pre-processing when converting doc comments to `about` / `long_about`
+- `next_display_order`: `clap::Command::next_display_order`
+- `next_help_heading`: `clap::Command::next_help_heading`
+ - When `flatten`ing `Args`, this is scoped to just the args in this struct and any struct `flatten`ed into it
+- `rename_all = <expr>`: Override default field / variant name case conversion for `Command::name` / `Arg::name`
+ - When not present: `kebab-case`
+ - Available values: `camelCase`, `kebab-case`, `PascalCase`, `SCREAMING_SNAKE_CASE`, `snake_case`, `lower`, `UPPER`, `verbatim`
+- `rename_all_env = <expr>`: Override default field name case conversion for env variables for `clap::Arg::env`
+ - When not present: `SCREAMING_SNAKE_CASE`
+ - Available values: `camelCase`, `kebab-case`, `PascalCase`, `SCREAMING_SNAKE_CASE`, `snake_case`, `lower`, `UPPER`, `verbatim`
+
+And for `Subcommand` variants:
+- `skip`: Ignore this variant
+- `flatten`: Delegates to the variant for more subcommands (must implement `Subcommand`)
+- `subcommand`: Nest subcommands under the current set of subcommands (must implement `Subcommand`)
+- `external_subcommand`: `clap::Command::allow_external_subcommand(true)`
+ - Variant must be either `Variant(Vec<String>)` or `Variant(Vec<OsString>)`
+
+### Arg Attributes
+
+These correspond to a `clap::Arg`.
+
+**Raw attributes:** Any [`Arg` method](https://docs.rs/clap/latest/clap/struct.Arg.html) can also be used as an attribute, see [Terminology](#terminology) for syntax.
+- e.g. `#[clap(max_values(3))]` would translate to `arg.max_values(3)`
+
+**Magic attributes**:
+- `name = <expr>`: `clap::Arg::new`
+ - When not present: case-converted field name is used
+- `value_parser [= <expr>]`: `clap::Arg::value_parser`
+ - When not present: will auto-select an implementation based on the field type
+ - To register a custom type's `ValueParser`, implement `ValueParserFactory`
+ - When present, implies `#[clap(action)]`
+- `action [= <expr>]`: `clap::Arg::action`
+ - When not present: will auto-select an action based on the field type
+ - When present, implies `#[clap(value_parser)]`
+- `help = <expr>`: `clap::Arg::help`
+ - When not present: [Doc comment summary](#doc-comments)
+- `long_help = <expr>`: `clap::Arg::long_help`
+ - When not present: [Doc comment](#doc-comments) if there is a blank line, else nothing
+- `verbatim_doc_comment`: Minimizes pre-processing when converting doc comments to `help` / `long_help`
+- `short [= <char>]`: `clap::Arg::short`
+ - When not present: no short set
+ - Without `<char>`: defaults to first character in the case-converted field name
+- `long [= <str>]`: `clap::Arg::long`
+ - When not present: no long set
+ - Without `<str>`: defaults to the case-converted field name
+- `env [= <str>]`: `clap::Arg::env` (needs `env` feature enabled)
+ - When not present: no env set
+ - Without `<str>`: defaults to the case-converted field name
+- `flatten`: Delegates to the field for more arguments (must implement `Args`)
+ - Only `help_heading` can be used with `flatten`. See
+ [clap-rs/clap#3269](https://github.com/clap-rs/clap/issues/3269) for why
+ arg attributes are not generally supported.
+ - **Tip:** Though we do apply a flattened `Args`'s Parent Command Attributes, this
+ makes reuse harder. Generally prefer putting the cmd attributes on the `Parser`
+ or on the flattened field.
+- `subcommand`: Delegates definition of subcommands to the field (must implement `Subcommand`)
+ - When `Option<T>`, the subcommand becomes optional
+- `from_global`: Read a `clap::Arg::global` argument (raw attribute), regardless of what subcommand you are in
+- `parse(<kind> [= <function>])`: `clap::Arg::validator` and `clap::ArgMatches::values_of_t`
+ - **Deprecated:**
+ - Use `value_parser(...)` for `from_str`, `try_from_str`, `from_os_str`, and `try_from_os_str`
+ - Use `action(ArgAction::Count` for `from_occurrences`
+ - Use `action(ArgAction::SetTrue` for `from_flag`
+ - Default: `try_from_str`
+ - Warning: for `Path` / `OsString`, be sure to use `try_from_os_str`
+ - See [Arg Types](#arg-types) for more details
+- `value_enum`: Parse the value using the `ValueEnum` trait
+- `skip [= <expr>]`: Ignore this field, filling in with `<expr>`
+ - Without `<expr>`: fills the field with `Default::default()`
+- `default_value = <str>`: `clap::Arg::default_value` and `clap::Arg::required(false)`
+- `default_value_t [= <expr>]`: `clap::Arg::default_value` and `clap::Arg::required(false)`
+ - Requires `std::fmt::Display` or `#[clap(value_enum)]`
+ - Without `<expr>`, relies on `Default::default()`
+- `default_value_os_t [= <expr>]`: `clap::Arg::default_value_os` and `clap::Arg::required(false)`
+ - Requires `std::convert::Into<OsString>` or `#[clap(value_enum)]`
+ - Without `<expr>`, relies on `Default::default()`
+
+### Arg Enum Attributes
+
+- `rename_all = <expr>`: Override default field / variant name case conversion for `PossibleValue::new`
+ - When not present: `kebab-case`
+ - Available values: `camelCase`, `kebab-case`, `PascalCase`, `SCREAMING_SNAKE_CASE`, `snake_case`, `lower`, `UPPER`, `verbatim`
+
+### Possible Value Attributes
+
+These correspond to a `clap::PossibleValue`.
+
+**Raw attributes:** Any [`PossibleValue` method](https://docs.rs/clap/latest/clap/struct.PossibleValue.html) can also be used as an attribute, see [Terminology](#terminology) for syntax.
+- e.g. `#[clap(alias("foo"))]` would translate to `pv.alias("foo")`
+
+**Magic attributes**:
+- `name = <expr>`: `clap::PossibleValue::new`
+ - When not present: case-converted field name is used
+- `help = <expr>`: `clap::PossibleValue::help`
+ - When not present: [Doc comment summary](#doc-comments)
+
+## Arg Types
+
+`clap` assumes some intent based on the type used:
+
+| Type | Effect | Implies |
+|---------------------|--------------------------------------|------------------------------------------------------------------|
+| `bool` | flag | `#[clap(parse(from_flag))]` |
+| `Option<T>` | optional argument | `.takes_value(true).required(false)` |
+| `Option<Option<T>>` | optional value for optional argument | `.takes_value(true).required(false).min_values(0).max_values(1)` |
+| `T` | required argument | `.takes_value(true).required(!has_default)` |
+| `Vec<T>` | `0..` occurrences of argument | `.takes_value(true).required(false).multiple_occurrences(true)` |
+| `Option<Vec<T>>` | `0..` occurrences of argument | `.takes_value(true).required(false).multiple_occurrences(true)` |
+
+Notes:
+- For custom type behavior, you can override the implied attributes/settings and/or set additional ones
+ - For example, see [custom-bool](./custom-bool.md)
+- `Option<Vec<T>>` will be `None` instead of `vec![]` if no arguments are provided.
+ - This gives the user some flexibility in designing their argument, like with `min_values(0)`
+
+You can then support your custom type with `#[clap(parse(<kind> [= <function>]))]`:
+
+| `<kind>` | Signature | Default `<function>` |
+|--------------------------|---------------------------------------|---------------------------------|
+| `from_str` | `fn(&str) -> T` | `::std::convert::From::from` |
+| `try_from_str` (default) | `fn(&str) -> Result<T, E>` | `::std::str::FromStr::from_str` |
+| `from_os_str` | `fn(&OsStr) -> T` | `::std::convert::From::from` |
+| `try_from_os_str` | `fn(&OsStr) -> Result<T, E>` | (no default function) |
+| `from_occurrences` | `fn(u64) -> T` | `value as T` |
+| `from_flag` | `fn(bool) -> T` | `::std::convert::From::from` |
+
+Notes:
+- `from_os_str`:
+ - Implies `arg.takes_value(true).allow_invalid_utf8(true)`
+- `try_from_os_str`:
+ - Implies `arg.takes_value(true).allow_invalid_utf8(true)`
+- `from_occurrences`:
+ - Implies `arg.takes_value(false).multiple_occurrences(true)`
+ - Reads from `clap::ArgMatches::occurrences_of` rather than a `get_one` function
+ - Note: operations on values, like `default_value`, are unlikely to do what you want
+- `from_flag`
+ - Implies `arg.takes_value(false)`
+ - Reads from `clap::ArgMatches::is_present` rather than a `get_one` function
+ - Note: operations on values, like `default_value`, are unlikely to do what you want
+
+**Warning:**
+- To support non-UTF8 paths, you should use `#[clap(value_parser)]` otherwise
+ `clap` will parse it as a `String` which will fail on some paths.
+
+## Doc Comments
+
+In clap, help messages for the whole binary can be specified
+via [`Command::about`] and [`Command::long_about`] while help messages
+for individual arguments can be specified via [`Arg::help`] and [`Arg::long_help`]".
+
+`long_*` variants are used when user calls the program with
+`--help` and "short" variants are used with `-h` flag.
+
+```rust
+# use clap::Parser;
+
+#[derive(Parser)]
+#[clap(about = "I am a program and I work, just pass `-h`", long_about = None)]
+struct Foo {
+ #[clap(short, help = "Pass `-h` and you'll see me!")]
+ bar: String,
+}
+```
+
+For convenience, doc comments can be used instead of raw methods
+(this example works exactly like the one above):
+
+```rust
+# use clap::Parser;
+
+#[derive(Parser)]
+/// I am a program and I work, just pass `-h`
+struct Foo {
+ /// Pass `-h` and you'll see me!
+ bar: String,
+}
+```
+
+**NOTE:** Attributes have priority over doc comments!
+
+**Top level doc comments always generate `Command::about/long_about` calls!**
+If you really want to use the `Command::about/long_about` methods (you likely don't),
+use the `about` / `long_about` attributes to override the calls generated from
+the doc comment. To clear `long_about`, you can use
+`#[clap(long_about = None)]`.
+
+**TIP:** Set `#![deny(missing_docs)]` to catch missing `--help` documentation at compile time.
+
+### Pre-processing
+
+```rust
+# use clap::Parser;
+#[derive(Parser)]
+/// Hi there, I'm Robo!
+///
+/// I like beeping, stumbling, eating your electricity,
+/// and making records of you singing in a shower.
+/// Pay up, or I'll upload it to youtube!
+struct Robo {
+ /// Call my brother SkyNet.
+ ///
+ /// I am artificial superintelligence. I won't rest
+ /// until I'll have destroyed humanity. Enjoy your
+ /// pathetic existence, you mere mortals.
+ #[clap(long, action)]
+ kill_all_humans: bool,
+}
+```
+
+A doc comment consists of three parts:
+- Short summary
+- A blank line (whitespace only)
+- Detailed description, all the rest
+
+The summary corresponds with `Command::about` / `Arg::help`. When a blank line is
+present, the whole doc comment will be passed to `Command::long_about` /
+`Arg::long_help`. Or in other words, a doc may result in just a `Command::about` /
+`Arg::help` or `Command::about` / `Arg::help` and `Command::long_about` /
+`Arg::long_help`
+
+In addition, when `verbatim_doc_comment` is not present, `clap` applies some preprocessing, including:
+
+- Strip leading and trailing whitespace from every line, if present.
+
+- Strip leading and trailing blank lines, if present.
+
+- Interpret each group of non-empty lines as a word-wrapped paragraph.
+
+ We replace newlines within paragraphs with spaces to allow the output
+ to be re-wrapped to the terminal width.
+
+- Strip any excess blank lines so that there is exactly one per paragraph break.
+
+- If the first paragraph ends in exactly one period,
+ remove the trailing period (i.e. strip trailing periods but not trailing ellipses).
+
+Sometimes you don't want this preprocessing to apply, for example the comment contains
+some ASCII art or markdown tables, you would need to preserve LFs along with
+blank lines and the leading/trailing whitespace. When you pass use the
+`verbatim_doc_comment` magic attribute, you preserve
+them.
+
+**Note:** Keep in mind that `verbatim_doc_comment` will *still*
+- Remove one leading space from each line, even if this attribute is present,
+ to allow for a space between `///` and the content.
+- Remove leading and trailing blank lines
+
+## Tips
+
+- To get access to a `Command` call `CommandFactory::command` (implemented when deriving `Parser`)
+- Proactively check for bad `Command` configurations by calling `Command::debug_assert` in a test ([example](../tutorial_derive/05_01_assert.rs))
+
+## Mixing Builder and Derive APIs
+
+The builder and derive APIs do not live in isolation. They can work together, which is especially helpful if some arguments can be specified at compile-time while others must be specified at runtime.
+
+### Using derived arguments in a builder application
+
+*[Jump to source](augment_args.rs)*
+
+When using the derive API, you can `#[clap(flatten)]` a struct deriving `Args` into a struct deriving `Args` or `Parser`. This example shows how you can augment a `Command` instance created using the builder API with `Args` created using the derive API.
+
+It uses the `Args::augment_args` method to add the arguments to the `Command` instance.
+
+Crates such as [clap-verbosity-flag](https://github.com/rust-cli/clap-verbosity-flag) provide structs that implement `Args` or `Parser`. Without the technique shown in this example, it would not be possible to use such crates with the builder API. `augment_args` to the rescue!
+
+### Using derived subcommands in a builder application
+
+*[Jump to source](augment_subcommands.rs)*
+
+When using the derive API, you can use `#[clap(subcommand)]` inside the struct to add subcommands. The type of the field is usually an enum that derived `Parser`. However, you can also add the subcommands in that enum to a `Command` instance created with the builder API.
+
+It uses the `Subcommand::augment_subcommands` method to add the subcommands to the `Command` instance.
+
+### Adding hand-implemented subcommands to a derived application
+
+*[Jump to source](hand_subcommand.rs)*
+
+When using the derive API, you can use `#[clap(subcommand)]` inside the struct to add subcommands. The type of the field is usually an enum that derived `Parser`. However, you can also implement the `Subcommand` trait manually on this enum (or any other type) and it can still be used inside the struct created with the derive API. The implementation of the `Subcommand` trait will use the builder API to add the subcommands to the `Command` instance created behind the scenes for you by the derive API.
+
+Notice how in the previous example we used `augment_subcommands` on an enum that derived `Parser`, whereas now we implement `augment_subcommands` ourselves, but the derive API calls it automatically since we used the `#[clap(subcommand)]` attribute.
+
+### Flattening hand-implemented args into a derived application
+
+*[Jump to source](flatten_hand_args.rs)*
+
+When using the derive API, you can use `#[clap(flatten)]` inside the struct to add arguments as if they were added directly to the containing struct. The type of the field is usually an struct that derived `Args`. However, you can also implement the `Args` trait manually on this struct (or any other type) and it can still be used inside the struct created with the derive API. The implementation of the `Args` trait will use the builder API to add the arguments to the `Command` instance created behind the scenes for you by the derive API.
+
+Notice how in the example 1 we used `augment_args` on the struct that derived `Parser`, whereas now we implement `augment_args` ourselves, but the derive API calls it automatically since we used the `#[clap(flatten)]` attribute.
diff --git a/vendor/clap/examples/derive_ref/augment_args.rs b/vendor/clap/examples/derive_ref/augment_args.rs
new file mode 100644
index 000000000..390c72f4a
--- /dev/null
+++ b/vendor/clap/examples/derive_ref/augment_args.rs
@@ -0,0 +1,30 @@
+use clap::{arg, Args as _, Command, FromArgMatches as _, Parser};
+
+#[derive(Parser, Debug)]
+struct DerivedArgs {
+ #[clap(short, long, action)]
+ derived: bool,
+}
+
+fn main() {
+ let cli = Command::new("CLI").arg(arg!(-b - -built).action(clap::ArgAction::SetTrue));
+ // Augment built args with derived args
+ let cli = DerivedArgs::augment_args(cli);
+
+ let matches = cli.get_matches();
+ println!(
+ "Value of built: {:?}",
+ *matches.get_one::<bool>("built").unwrap()
+ );
+ println!(
+ "Value of derived via ArgMatches: {:?}",
+ *matches.get_one::<bool>("derived").unwrap()
+ );
+
+ // Since DerivedArgs implements FromArgMatches, we can extract it from the unstructured ArgMatches.
+ // This is the main benefit of using derived arguments.
+ let derived_matches = DerivedArgs::from_arg_matches(&matches)
+ .map_err(|err| err.exit())
+ .unwrap();
+ println!("Value of derived: {:#?}", derived_matches);
+}
diff --git a/vendor/clap/examples/derive_ref/augment_subcommands.rs b/vendor/clap/examples/derive_ref/augment_subcommands.rs
new file mode 100644
index 000000000..199da98b4
--- /dev/null
+++ b/vendor/clap/examples/derive_ref/augment_subcommands.rs
@@ -0,0 +1,21 @@
+use clap::{Command, FromArgMatches as _, Parser, Subcommand as _};
+
+#[derive(Parser, Debug)]
+enum Subcommands {
+ Derived {
+ #[clap(short, long, action)]
+ derived_flag: bool,
+ },
+}
+
+fn main() {
+ let cli = Command::new("Built CLI");
+ // Augment with derived subcommands
+ let cli = Subcommands::augment_subcommands(cli);
+
+ let matches = cli.get_matches();
+ let derived_subcommands = Subcommands::from_arg_matches(&matches)
+ .map_err(|err| err.exit())
+ .unwrap();
+ println!("Derived subcommands: {:#?}", derived_subcommands);
+}
diff --git a/vendor/clap/examples/derive_ref/custom-bool.md b/vendor/clap/examples/derive_ref/custom-bool.md
new file mode 100644
index 000000000..619f9ba8e
--- /dev/null
+++ b/vendor/clap/examples/derive_ref/custom-bool.md
@@ -0,0 +1,47 @@
+*Jump to [source](custom-bool.rs)*
+
+Example of overriding the magic `bool` behavior
+
+```console
+$ custom-bool --help
+clap [..]
+A simple to use, efficient, and full-featured Command Line Argument Parser
+
+USAGE:
+ custom-bool[EXE] [OPTIONS] --foo <FOO> <BOOM>
+
+ARGS:
+ <BOOM> [possible values: true, false]
+
+OPTIONS:
+ --bar <BAR> [default: false]
+ --foo <FOO> [possible values: true, false]
+ -h, --help Print help information
+ -V, --version Print version information
+
+$ custom-bool
+? failed
+error: The following required arguments were not provided:
+ --foo <FOO>
+ <BOOM>
+
+USAGE:
+ custom-bool[EXE] [OPTIONS] --foo <FOO> <BOOM>
+
+For more information try --help
+
+$ custom-bool --foo true false
+[examples/derive_ref/custom-bool.rs:31] opt = Opt {
+ foo: true,
+ bar: false,
+ boom: false,
+}
+
+$ custom-bool --foo true --bar true false
+[examples/derive_ref/custom-bool.rs:31] opt = Opt {
+ foo: true,
+ bar: true,
+ boom: false,
+}
+
+```
diff --git a/vendor/clap/examples/derive_ref/custom-bool.rs b/vendor/clap/examples/derive_ref/custom-bool.rs
new file mode 100644
index 000000000..d3c321e72
--- /dev/null
+++ b/vendor/clap/examples/derive_ref/custom-bool.rs
@@ -0,0 +1,32 @@
+use clap::Parser;
+
+#[derive(Parser, Debug, PartialEq)]
+#[clap(author, version, about, long_about = None)]
+struct Opt {
+ // Default parser for `Set` is FromStr::from_str.
+ // `impl FromStr for bool` parses `true` or `false` so this
+ // works as expected.
+ #[clap(long, action = clap::ArgAction::Set)]
+ foo: bool,
+
+ // Of course, this could be done with an explicit parser function.
+ #[clap(long, action = clap::ArgAction::Set, value_parser = true_or_false, default_value_t)]
+ bar: bool,
+
+ // `bool` can be positional only with explicit `action` annotation
+ #[clap(action = clap::ArgAction::Set)]
+ boom: bool,
+}
+
+fn true_or_false(s: &str) -> Result<bool, &'static str> {
+ match s {
+ "true" => Ok(true),
+ "false" => Ok(false),
+ _ => Err("expected `true` or `false`"),
+ }
+}
+
+fn main() {
+ let opt = Opt::parse();
+ dbg!(opt);
+}
diff --git a/vendor/clap/examples/derive_ref/flatten_hand_args.rs b/vendor/clap/examples/derive_ref/flatten_hand_args.rs
new file mode 100644
index 000000000..74d10edec
--- /dev/null
+++ b/vendor/clap/examples/derive_ref/flatten_hand_args.rs
@@ -0,0 +1,81 @@
+use clap::error::Error;
+use clap::{Arg, ArgAction, ArgMatches, Args, Command, FromArgMatches, Parser};
+
+#[derive(Debug)]
+struct CliArgs {
+ foo: bool,
+ bar: bool,
+ quuz: Option<String>,
+}
+
+impl FromArgMatches for CliArgs {
+ fn from_arg_matches(matches: &ArgMatches) -> Result<Self, Error> {
+ let mut matches = matches.clone();
+ Self::from_arg_matches_mut(&mut matches)
+ }
+ fn from_arg_matches_mut(matches: &mut ArgMatches) -> Result<Self, Error> {
+ Ok(Self {
+ foo: *matches.get_one::<bool>("foo").expect("defaulted by clap"),
+ bar: *matches.get_one::<bool>("bar").expect("defaulted by clap"),
+ quuz: matches.remove_one::<String>("quuz"),
+ })
+ }
+ fn update_from_arg_matches(&mut self, matches: &ArgMatches) -> Result<(), Error> {
+ let mut matches = matches.clone();
+ self.update_from_arg_matches_mut(&mut matches)
+ }
+ fn update_from_arg_matches_mut(&mut self, matches: &mut ArgMatches) -> Result<(), Error> {
+ self.foo |= *matches.get_one::<bool>("foo").expect("defaulted by clap");
+ self.bar |= *matches.get_one::<bool>("bar").expect("defaulted by clap");
+ if let Some(quuz) = matches.remove_one::<String>("quuz") {
+ self.quuz = Some(quuz);
+ }
+ Ok(())
+ }
+}
+
+impl Args for CliArgs {
+ fn augment_args(cmd: Command<'_>) -> Command<'_> {
+ cmd.arg(
+ Arg::new("foo")
+ .short('f')
+ .long("foo")
+ .action(ArgAction::SetTrue),
+ )
+ .arg(
+ Arg::new("bar")
+ .short('b')
+ .long("bar")
+ .action(ArgAction::SetTrue),
+ )
+ .arg(Arg::new("quuz").short('q').long("quuz").takes_value(true))
+ }
+ fn augment_args_for_update(cmd: Command<'_>) -> Command<'_> {
+ cmd.arg(
+ Arg::new("foo")
+ .short('f')
+ .long("foo")
+ .action(ArgAction::SetTrue),
+ )
+ .arg(
+ Arg::new("bar")
+ .short('b')
+ .long("bar")
+ .action(ArgAction::SetTrue),
+ )
+ .arg(Arg::new("quuz").short('q').long("quuz").takes_value(true))
+ }
+}
+
+#[derive(Parser, Debug)]
+struct Cli {
+ #[clap(short, long, action)]
+ top_level: bool,
+ #[clap(flatten)]
+ more_args: CliArgs,
+}
+
+fn main() {
+ let args = Cli::parse();
+ println!("{:#?}", args);
+}
diff --git a/vendor/clap/examples/derive_ref/hand_subcommand.rs b/vendor/clap/examples/derive_ref/hand_subcommand.rs
new file mode 100644
index 000000000..e9423bdc0
--- /dev/null
+++ b/vendor/clap/examples/derive_ref/hand_subcommand.rs
@@ -0,0 +1,81 @@
+use clap::error::{Error, ErrorKind};
+use clap::{ArgMatches, Args as _, Command, FromArgMatches, Parser, Subcommand};
+
+#[derive(Parser, Debug)]
+struct AddArgs {
+ #[clap(value_parser)]
+ name: Vec<String>,
+}
+#[derive(Parser, Debug)]
+struct RemoveArgs {
+ #[clap(short, long, action)]
+ force: bool,
+ #[clap(value_parser)]
+ name: Vec<String>,
+}
+
+#[derive(Debug)]
+enum CliSub {
+ Add(AddArgs),
+ Remove(RemoveArgs),
+}
+
+impl FromArgMatches for CliSub {
+ fn from_arg_matches(matches: &ArgMatches) -> Result<Self, Error> {
+ match matches.subcommand() {
+ Some(("add", args)) => Ok(Self::Add(AddArgs::from_arg_matches(args)?)),
+ Some(("remove", args)) => Ok(Self::Remove(RemoveArgs::from_arg_matches(args)?)),
+ Some((_, _)) => Err(Error::raw(
+ ErrorKind::UnrecognizedSubcommand,
+ "Valid subcommands are `add` and `remove`",
+ )),
+ None => Err(Error::raw(
+ ErrorKind::MissingSubcommand,
+ "Valid subcommands are `add` and `remove`",
+ )),
+ }
+ }
+ fn update_from_arg_matches(&mut self, matches: &ArgMatches) -> Result<(), Error> {
+ match matches.subcommand() {
+ Some(("add", args)) => *self = Self::Add(AddArgs::from_arg_matches(args)?),
+ Some(("remove", args)) => *self = Self::Remove(RemoveArgs::from_arg_matches(args)?),
+ Some((_, _)) => {
+ return Err(Error::raw(
+ ErrorKind::UnrecognizedSubcommand,
+ "Valid subcommands are `add` and `remove`",
+ ))
+ }
+ None => (),
+ };
+ Ok(())
+ }
+}
+
+impl Subcommand for CliSub {
+ fn augment_subcommands(cmd: Command<'_>) -> Command<'_> {
+ cmd.subcommand(AddArgs::augment_args(Command::new("add")))
+ .subcommand(RemoveArgs::augment_args(Command::new("remove")))
+ .subcommand_required(true)
+ }
+ fn augment_subcommands_for_update(cmd: Command<'_>) -> Command<'_> {
+ cmd.subcommand(AddArgs::augment_args(Command::new("add")))
+ .subcommand(RemoveArgs::augment_args(Command::new("remove")))
+ .subcommand_required(true)
+ }
+ fn has_subcommand(name: &str) -> bool {
+ matches!(name, "add" | "remove")
+ }
+}
+
+#[derive(Parser, Debug)]
+struct Cli {
+ #[clap(short, long, action)]
+ top_level: bool,
+ #[clap(subcommand)]
+ subcommand: CliSub,
+}
+
+fn main() {
+ let args = Cli::parse();
+ println!("{:#?}", args);
+}
diff --git a/vendor/clap/examples/derive_ref/interop_tests.md b/vendor/clap/examples/derive_ref/interop_tests.md
new file mode 100644
index 000000000..746fe1878
--- /dev/null
+++ b/vendor/clap/examples/derive_ref/interop_tests.md
@@ -0,0 +1,256 @@
+Following are tests for the interop examples in this directory.
+
+## Augment Args
+
+```console
+$ interop_augment_args
+Value of built: false
+Value of derived via ArgMatches: false
+Value of derived: DerivedArgs {
+ derived: false,
+}
+
+```
+
+```console
+$ interop_augment_args -b --derived
+Value of built: true
+Value of derived via ArgMatches: true
+Value of derived: DerivedArgs {
+ derived: true,
+}
+
+```
+
+```console
+$ interop_augment_args -d --built
+Value of built: true
+Value of derived via ArgMatches: true
+Value of derived: DerivedArgs {
+ derived: true,
+}
+
+```
+
+```console
+$ interop_augment_args --unknown
+? failed
+error: Found argument '--unknown' which wasn't expected, or isn't valid in this context
+
+ If you tried to supply `--unknown` as a value rather than a flag, use `-- --unknown`
+
+USAGE:
+ interop_augment_args[EXE] [OPTIONS]
+
+For more information try --help
+
+```
+
+## Augment Subcommands
+
+```console
+$ interop_augment_subcommands
+? failed
+error: A subcommand is required but one was not provided.
+```
+
+```console
+$ interop_augment_subcommands derived
+Derived subcommands: Derived {
+ derived_flag: false,
+}
+
+```
+
+```console
+$ interop_augment_subcommands derived --derived-flag
+Derived subcommands: Derived {
+ derived_flag: true,
+}
+
+```
+
+```console
+$ interop_augment_subcommands derived --unknown
+? failed
+error: Found argument '--unknown' which wasn't expected, or isn't valid in this context
+
+ If you tried to supply `--unknown` as a value rather than a flag, use `-- --unknown`
+
+USAGE:
+ interop_augment_subcommands[EXE] derived [OPTIONS]
+
+For more information try --help
+
+```
+
+```console
+$ interop_augment_subcommands unknown
+? failed
+error: Found argument 'unknown' which wasn't expected, or isn't valid in this context
+
+USAGE:
+ interop_augment_subcommands[EXE] [SUBCOMMAND]
+
+For more information try --help
+
+```
+
+## Hand-Implemented Subcommand
+
+```console
+$ interop_hand_subcommand
+? failed
+error: 'interop_hand_subcommand[EXE]' requires a subcommand but one was not provided
+
+USAGE:
+ interop_hand_subcommand[EXE] [OPTIONS] <SUBCOMMAND>
+
+For more information try --help
+
+```
+
+```console
+$ interop_hand_subcommand add
+Cli {
+ top_level: false,
+ subcommand: Add(
+ AddArgs {
+ name: [],
+ },
+ ),
+}
+
+```
+
+```console
+$ interop_hand_subcommand add a b c
+Cli {
+ top_level: false,
+ subcommand: Add(
+ AddArgs {
+ name: [
+ "a",
+ "b",
+ "c",
+ ],
+ },
+ ),
+}
+
+```
+
+```console
+$ interop_hand_subcommand add --unknown
+? failed
+error: Found argument '--unknown' which wasn't expected, or isn't valid in this context
+
+ If you tried to supply `--unknown` as a value rather than a flag, use `-- --unknown`
+
+USAGE:
+ interop_hand_subcommand[EXE] add [NAME]...
+
+For more information try --help
+
+```
+
+```console
+$ interop_hand_subcommand remove
+Cli {
+ top_level: false,
+ subcommand: Remove(
+ RemoveArgs {
+ force: false,
+ name: [],
+ },
+ ),
+}
+
+```
+
+```console
+$ interop_hand_subcommand remove --force a b c
+Cli {
+ top_level: false,
+ subcommand: Remove(
+ RemoveArgs {
+ force: true,
+ name: [
+ "a",
+ "b",
+ "c",
+ ],
+ },
+ ),
+}
+
+```
+
+```console
+$ interop_hand_subcommand unknown
+? failed
+error: Found argument 'unknown' which wasn't expected, or isn't valid in this context
+
+USAGE:
+ interop_hand_subcommand[EXE] [OPTIONS] <SUBCOMMAND>
+
+For more information try --help
+
+```
+
+## Flatten Hand-Implemented Args
+
+```console
+$ interop_flatten_hand_args
+Cli {
+ top_level: false,
+ more_args: CliArgs {
+ foo: false,
+ bar: false,
+ quuz: None,
+ },
+}
+
+```
+
+```console
+$ interop_flatten_hand_args -f --bar
+Cli {
+ top_level: false,
+ more_args: CliArgs {
+ foo: true,
+ bar: true,
+ quuz: None,
+ },
+}
+
+```
+
+```console
+$ interop_flatten_hand_args --quuz abc
+Cli {
+ top_level: false,
+ more_args: CliArgs {
+ foo: false,
+ bar: false,
+ quuz: Some(
+ "abc",
+ ),
+ },
+}
+
+```
+
+```console
+$ interop_flatten_hand_args --unknown
+? failed
+error: Found argument '--unknown' which wasn't expected, or isn't valid in this context
+
+ If you tried to supply `--unknown` as a value rather than a flag, use `-- --unknown`
+
+USAGE:
+ interop_flatten_hand_args[EXE] [OPTIONS]
+
+For more information try --help
+
+```