structopt-0.3.26/.cargo_vcs_info.json0000644000000001360000000000100131730ustar { "git": { "sha1": "97e92a3755a65f8ea44c994fd403208e7d97f561" }, "path_in_vcs": "" }structopt-0.3.26/.gitignore000064400000000000000000000000620072674642500140010ustar 00000000000000target Cargo.lock *~ expanded.rs .idea/ .vscode/ structopt-0.3.26/.travis.yml000064400000000000000000000015410072674642500141250ustar 00000000000000if: type != push OR branch = master language: rust matrix: include: - rust: stable name: check if `cargo fmt --all` is applied before_script: rustup component add rustfmt-preview script: cargo fmt --all -- --check - language: node_js node_js: node name: check links install: npm install -g markdown-link-check script: - markdown-link-check -c link-check-headers.json README.md - markdown-link-check -c link-check-headers.json CHANGELOG.md - markdown-link-check -c link-check-headers.json examples/README.md - rust: stable name: clippy before_script: rustup component add clippy script: cargo clippy --all -- -D warnings - rust: 1.46.0 - rust: stable - rust: beta - rust: nightly script: - cargo test jobs: allow_failures: - name: clippy structopt-0.3.26/CHANGELOG.md000064400000000000000000000511450072674642500136320ustar 00000000000000# v0.3.25 (2021-10-18) * Fix duplication of aliases in subcommands [#504](https://github.com/TeXitoi/structopt/pull/504) # v0.3.25 (2021-10-18) * No changes # v0.3.23 (2021-08-30) * Update minimal rust version to 1.46 because of bitflags 1.3 * Fixed [a bug that occurs when the type of `map` becomes ambiguous](https://github.com/TeXitoi/structopt/issues/490). * Add support for [skip for enum variant subcommands](https://github.com/TeXitoi/structopt/issues/493) # v0.3.22 (2021-07-04) * Add support for [generics in derive](https://github.com/TeXitoi/structopt/issues/128) # v0.3.21 (2020-11-30) * Fixed [another breakage](https://github.com/TeXitoi/structopt/issues/447) when the struct is placed inside a `macro_rules!` macro. # v0.3.20 (2020-10-12) * Fixed [a breakage](https://github.com/TeXitoi/structopt/issues/439) when the struct is placed inside a `macro_rules!` macro. # v0.3.19 (2020-10-08) * Added [StructOpt::from_args_safe](https://docs.rs/structopt/0.3/structopt/trait.StructOpt.html#tymethod.from_args_safe) as a shortcut for `StructOpt::from_iter_safe(std::env::args_os())`. * Some links in documentation have been corrected. # v0.3.18 (2020-09-23) * Unsafe code [has been forbidden](https://github.com/TeXitoi/structopt/issues/432). This makes [`cargo geiger`](https://github.com/rust-secure-code/cargo-geiger) list structopt as "safe". Maybe it will help somebody trying to locate a bug in their dependency tree. # v0.3.17 (2020-08-25) * Fixed [a breakage](https://github.com/TeXitoi/structopt/issues/424) with resent rustc versions due to `quote_spanned` misuse. # v0.3.16 (2020-08-05) * Added [the new example](https://github.com/TeXitoi/structopt/blob/master/examples/required_if.rs). * Allow `#[structopt(flatten)]` fields to have doc comments. The comments are ignored. * The `paw` crate is now being reexported when `paw` feature is enabled, see [`#407`](https://github.com/TeXitoi/structopt/issues/407). # v0.3.15 (2020-06-16) * Minor documentation improvements. * Fixed [a latent bug](https://github.com/TeXitoi/structopt/pull/398), courtesy of [@Aaron1011](https://github.com/Aaron1011). # v0.3.14 (2020-04-22) * Minor documentation improvements. # v0.3.13 (2020-04-9) * Bump `proc-macro-error` to `1.0`. # v0.3.12 (2020-03-18) * Fixed [bug in `external_subcommand`](https://github.com/TeXitoi/structopt/issues/359). # v0.3.11 (2020-03-01) * `syn`'s "full" feature is now explicitly enabled. It must have been, but hasn't. # v0.3.10 (2020-03-01) - YANKED * Fixed the breakage due to a required `syn` feature was not enabled. # v0.3.9 (2020-02-01) - YANKED * `clippy` warnings triggered by generated code shall not annoy you anymore! Except for those from `clippy::correctness`, these lints are useful even for auto generated code. * Improved error messages. # v0.3.8 (2020-1-19) - YANKED * You don't have to apply `#[no_version]` to every `enum` variant anymore. Just annotate the `enum` and the setting will be propagated down ([#242](https://github.com/TeXitoi/structopt/issues/242)). * [Auto-default](https://docs.rs/structopt/0.3/structopt/#default-values). * [External subcommands](https://docs.rs/structopt/0.3/structopt/#external-subcommands). * [Flattening subcommands](https://docs.rs/structopt/0.3.8/structopt/#flattening-subcommands). # v0.3.7 (2019-12-28) Nothing's new. Just re-release of `v0.3.6` due to [the mess with versioning](https://github.com/TeXitoi/structopt/issues/315#issuecomment-568502792). You may notice that `structopt-derive` was bumped to `v0.4.0`, that's OK, it's not a breaking change. `structopt` will pull the right version in on its on. # v0.3.6 (2019-12-22) - YANKED This is unusually big patch release. It contains a number of bugfixes and new features, some of them may theoretically be considered breaking. We did our best to avoid any problems on user's side but, if it wasn't good enough, please [file an issue ASAP](https://github.com/TeXitoi/structopt/issues). ## Bugfixes * `structopt` used to treat `::path::to::type::Vec` as `Vec` special type. [This was considered erroneous](https://github.com/TeXitoi/structopt/pull/287). (same for `Option` and `bool`). Now only exact `Vec` match is a special type. * `#[structopt(version = expr)]` where `expr` is not a string literal used to get overridden by auto generated `.version()` call, [incorrectly](https://github.com/TeXitoi/structopt/issues/283). Now it doesn't. * Fixed bug with top-level `App::*` calls on multiple `struct`s, see [#289](https://github.com/TeXitoi/structopt/issues/265). * Positional `bool` args with no explicit `#[structopt(parse(...))]` annotation are now prohibited. This couldn't work well anyway, see [this example](https://github.com/TeXitoi/structopt/blob/master/examples/true_or_false.rs) for details. * Now we've instituted strict priority between doc comments, about, help, and the like. See [the documentation](https://docs.rs/structopt/0.3/structopt/#help-messages). **HUGE THANKS to [`@ssokolow`](https://github.com/ssokolow)** for tidying up our documentation, teaching me English and explaining why our doc used to suck. I promise I'll make the rest of the doc up to your standards... sometime later! ## New features * Implement `StructOpt` for `Box` so from now on you can use `Box` with `flatten` and `subcommand` ([#304](https://github.com/TeXitoi/structopt/issues/304)). ```rust enum Command { #[structopt(name = "version")] PrintVersion, #[structopt(name = "second")] DoSomething { #[structopt(flatten)] config: Box, }, #[structopt(name = "first")] DoSomethingElse { #[structopt(flatten)] config: Box, } } ``` * Introduced `#[structopt(verbatim_doc_comment)]` attribute that keeps line breaks in doc comments, see [the documentation](https://docs.rs/structopt/0.3/structopt/#doc-comment-preprocessing-and-structoptverbatim_doc_comment). * Introduced `#[structopt(rename_all_env)]` and `#[structopt(env)]` magical methods so you can derive env var's name from field's name. See [the documentation](https://docs.rs/structopt/0.3/structopt/#auto-deriving-environment-variables). ## Improvements * Now we have nice README for our examples, [check it out](https://github.com/TeXitoi/structopt/tree/master/examples)! * Some error messages were improved and clarified, thanks for all people involved! # v0.3.5 (2019-11-22) * `try_from_str` functions are now called with a `&str` instead of a `&String` ([#282](https://github.com/TeXitoi/structopt/pull/282)) # v0.3.4 (2019-11-08) * `rename_all` does not apply to fields that were annotated with explicit `short/long/name = "..."` anymore ([#265](https://github.com/TeXitoi/structopt/issues/265)) * Now raw idents are handled correctly ([#269](https://github.com/TeXitoi/structopt/issues/269)) * Some documentation improvements and clarification. # v0.3.3 (2019-10-10) * Add `from_flag` custom parser to create flags from non-bool types. Fixes [#185](https://github.com/TeXitoi/structopt/issues/185) # v0.3.2 (2019-09-18) * `structopt` does not replace `:` with `, ` inside "author" strings while inside `<...>`. Fixes [#156](https://github.com/TeXitoi/structopt/issues/156) * Introduced [`#[structopt(skip = expr)]` syntax](https://docs.rs/structopt/0.3.2/structopt/#skipping-fields). # v0.3.1 (2019-09-06) * Fix error messages ([#241](https://github.com/TeXitoi/structopt/issues/241)) * Fix "`skip` plus long doc comment" bug ([#245](https://github.com/TeXitoi/structopt/issues/245)) * Now `structopt` emits dummy `StructOpt` implementation along with an error. It suppresses meaningless errors like `from_args method is not found for Opt` * `.version()` not get generated if `CARGO_PKG_VERSION` is not set anymore. # v0.3.0 (2019-08-30) ## Breaking changes ### Bump minimum rustc version to 1.36 by [@TeXitoi](https://github.com/TeXitoi) Now `rustc` 1.36 is the minimum compiler version supported by `structopt`, it likely won't work with older compilers. ### Remove "nightly" feature Once upon a time this feature had been used to enable some of improvements in `proc-macro2` crate that were available only on nightly. Nowadays this feature doesn't mean anything so it's now removed. ### Support optional vectors of arguments for distinguishing between `-o 1 2`, `-o` and no option provided at all by [@sphynx](https://github.com/sphynx) ([#180](https://github.com/TeXitoi/structopt/issues/188)). ```rust #[derive(StructOpt)] struct Opt { #[structopt(long)] fruit: Option>, } fn main() { assert_eq!(Opt::from_args(&["test"]), None); assert_eq!(Opt::from_args(&["test", "--fruit"]), Some(vec![])); assert_eq!(Opt::from_args(&["test", "--fruit=apple orange"]), Some(vec!["apple", "orange"])); } ``` If you need to fall back to the old behavior you can use a type alias: ```rust type Something = Vec; #[derive(StructOpt)] struct Opt { #[structopt(long)] fruit: Option, } ``` ### Change default case from 'Verbatim' into 'Kebab' by [@0ndorio](https://github.com/0ndorio) ([#202](https://github.com/TeXitoi/structopt/issues/202)). `structopt` 0.3 uses field renaming to deduce a name for long options and subcommands. ```rust #[derive(StructOpt)] struct Opt { #[structopt(long)] http_addr: String, // will be renamed to `--http-addr` #[structopt(subcommand)] addr_type: AddrType // this adds `addr-type` subcommand } ``` `structopt` 0.2 used to leave things "as is", not renaming anything. If you want to keep old behavior add `#[structopt(rename_all = "verbatim")]` on top of a `struct`/`enum`. ### Change `version`, `author` and `about` attributes behavior. Proposed by [@TeXitoi](https://github.com/TeXitoi) [(#217)](https://github.com/TeXitoi/structopt/issues/217), implemented by [@CreepySkeleton](https://github.com/CreepySkeleton) [(#229)](https://github.com/TeXitoi/structopt/pull/229). `structopt` have been deducing `version`, `author`, and `about` properties from `Cargo.toml` for a long time (more accurately, from `CARGO_PKG_...` environment variables). But many users found this behavior somewhat confusing, and a hack was added to cancel out this behavior: `#[structopt(author = "")]`. In `structopt` 0.3 this has changed. * `author` and `about` are no longer deduced by default. You should use `#[structopt(author, about)]` to explicitly request `structopt` to deduce them. * Contrary, `version` **is still deduced by default**. You can use `#[structopt(no_version)]` to cancel it out. * `#[structopt(author = "", about = "", version = "")]` is no longer a valid syntax and will trigger an error. * `#[structopt(version = "version", author = "author", about = "about")]` syntax stays unaffected by this changes. ### Raw attributes are removed ([#198](https://github.com/TeXitoi/structopt/pull/198)) by [@sphynx](https://github.com/sphynx) In `structopt` 0.2 you were able to use any method from `clap::App` and `clap::Arg` via raw attribute: `#[structopt(raw(method_name = "arg"))]`. This syntax was kind of awkward. ```rust #[derive(StructOpt, Debug)] #[structopt(raw( global_settings = "&[AppSettings::ColoredHelp, AppSettings::VersionlessSubcommands]" ))] struct Opt { #[structopt(short = "l", long = "level", raw(aliases = r#"&["set-level", "lvl"]"#))] level: Vec, } ``` Raw attributes were removed in 0.3. Now you can use any method from `App` and `Arg` *directly*: ```rust #[derive(StructOpt)] #[structopt(global_settings(&[AppSettings::ColoredHelp, AppSettings::VersionlessSubcommands]))] struct Opt { #[structopt(short = "l", long = "level", aliases(&["set-level", "lvl"]))] level: Vec, } ``` ## Improvements ### Support skipping struct fields Proposed by [@Morganamilo](https://github.com/Morganamilo) in ([#174](https://github.com/TeXitoi/structopt/issues/174)) implemented by [@sphynx](https://github.com/sphynx) in ([#213](https://github.com/TeXitoi/structopt/issues/213)). Sometimes you want to include some fields in your `StructOpt` `struct` that are not options and `clap` should know nothing about them. In `structopt` 0.3 it's possible via the `#[structopt(skip)]` attribute. The field in question will be assigned with `Default::default()` value. ```rust #[derive(StructOpt)] struct Opt { #[structopt(short, long)] speed: f32, car: String, // this field should not generate any arguments #[structopt(skip)] meta: Vec } ``` ### Add optional feature to support `paw` by [@gameldar](https://github.com/gameldar) ([#187](https://github.com/TeXitoi/structopt/issues/187)) ### Significantly improve error reporting by [@CreepySkeleton](https://github.com/CreepySkeleton) ([#225](https://github.com/TeXitoi/structopt/pull/225/)) Now (almost) every error message points to the location it originates from: ```text error: default_value is meaningless for bool --> $DIR/bool_default_value.rs:14:24 | 14 | #[structopt(short, default_value = true)] | ^^^^^^^^^^^^^ ``` # v0.2.16 (2019-05-29) ### Support optional options with optional argument, allowing `cmd [--opt[=value]]` by [@sphynx](https://github.com/sphynx) ([#188](https://github.com/TeXitoi/structopt/issues/188)) Sometimes you want to represent an optional option that optionally takes an argument, i.e `[--opt[=value]]`. This is represented by `Option>` ```rust #[derive(StructOpt)] struct Opt { #[structopt(long)] fruit: Option>, } fn main() { assert_eq!(Opt::from_args(&["test"]), None); assert_eq!(Opt::from_args(&["test", "--fruit"]), Some(None)); assert_eq!(Opt::from_args(&["test", "--fruit=apple"]), Some("apple")); } ``` # v0.2.15 (2019-03-08) * Fix [#168](https://github.com/TeXitoi/structopt/issues/168) by [@TeXitoi](https://github.com/TeXitoi) # v0.2.14 (2018-12-10) * Introduce smarter parsing of doc comments by [@0ndorio](https://github.com/0ndorio) # v0.2.13 (2018-11-01) * Automatic naming of fields and subcommands by [@0ndorio](https://github.com/0ndorio) # v0.2.12 (2018-10-11) * Fix minimal clap version by [@TeXitoi](https://github.com/TeXitoi) # v0.2.11 (2018-10-05) * Upgrade syn to 0.15 by [@konstin](https://github.com/konstin) # v0.2.10 (2018-06-07) * 1.21.0 is the minimum required rustc version by [@TeXitoi](https://github.com/TeXitoi) # v0.2.9 (2018-06-05) * Fix a bug when using `flatten` by [@fbenkstein](https://github.com/fbenkstein) * Update syn, quote and proc_macro2 by [@TeXitoi](https://github.com/TeXitoi) * Fix a regression when there is multiple authors by [@windwardly](https://github.com/windwardly) # v0.2.8 (2018-04-28) * Add `StructOpt::from_iter_safe()`, which returns an `Error` instead of killing the program when it fails to parse, or parses one of the short-circuiting flags. ([#98](https://github.com/TeXitoi/structopt/pull/98) by [@quodlibetor](https://github.com/quodlibetor)) * Allow users to enable `clap` features independently by [@Kerollmops](https://github.com/Kerollmops) * Fix a bug when flattening an enum ([#103](https://github.com/TeXitoi/structopt/pull/103) by [@TeXitoi](https://github.com/TeXitoi) # v0.2.7 (2018-04-12) * Add flattening, the insertion of options of another StructOpt struct into another ([#92](https://github.com/TeXitoi/structopt/pull/92)) by [@birkenfeld](https://github.com/birkenfeld) * Fail compilation when using `default_value` or `required` with `Option` ([#88](https://github.com/TeXitoi/structopt/pull/88)) by [@Kerollmops](https://github.com/Kerollmops) # v0.2.6 (2018-03-31) * Fail compilation when using `default_value` or `required` with `bool` ([#80](https://github.com/TeXitoi/structopt/issues/80)) by [@TeXitoi](https://github.com/TeXitoi) * Fix compilation with `#[deny(warnings)]` with the `!` type (https://github.com/rust-lang/rust/pull/49039#issuecomment-376398999) by [@TeXitoi](https://github.com/TeXitoi) * Improve first example in the documentation ([#82](https://github.com/TeXitoi/structopt/issues/82)) by [@TeXitoi](https://github.com/TeXitoi) # v0.2.5 (2018-03-07) * Work around breakage when `proc-macro2`'s nightly feature is enabled. ([#77](https://github.com/Texitoi/structopt/pull/77) and [proc-macro2#67](https://github.com/alexcrichton/proc-macro2/issues/67)) by [@fitzgen](https://github.com/fitzgen) # v0.2.4 (2018-02-25) * Fix compilation with `#![deny(missig_docs]` ([#74](https://github.com/TeXitoi/structopt/issues/74)) by [@TeXitoi](https://github.com/TeXitoi) * Fix [#76](https://github.com/TeXitoi/structopt/issues/76) by [@TeXitoi](https://github.com/TeXitoi) * Re-licensed to Apache-2.0/MIT by [@CAD97](https://github.com/cad97) # v0.2.3 (2018-02-16) * An empty line in a doc comment will result in a double linefeed in the generated about/help call by [@TeXitoi](https://github.com/TeXitoi) # v0.2.2 (2018-02-12) * Fix [#66](https://github.com/TeXitoi/structopt/issues/66) by [@TeXitoi](https://github.com/TeXitoi) # v0.2.1 (2018-02-11) * Fix a bug around enum tuple and the about message in the global help by [@TeXitoi](https://github.com/TeXitoi) * Fix [#65](https://github.com/TeXitoi/structopt/issues/65) by [@TeXitoi](https://github.com/TeXitoi) # v0.2.0 (2018-02-10) ## Breaking changes ### Don't special case `u64` by [@SergioBenitez](https://github.com/SergioBenitez) If you are using a `u64` in your struct to get the number of occurence of a flag, you should now add `parse(from_occurrences)` on the flag. For example ```rust #[structopt(short = "v", long = "verbose")] verbose: u64, ``` must be changed by ```rust #[structopt(short = "v", long = "verbose", parse(from_occurrences))] verbose: u64, ``` This feature was surprising as shown in [#30](https://github.com/TeXitoi/structopt/issues/30). Using the `parse` feature seems much more natural. ### Change the signature of `Structopt::from_clap` to take its argument by reference by [@TeXitoi](https://github.com/TeXitoi) There was no reason to take the argument by value. Most of the StructOpt users will not be impacted by this change. If you are using `StructOpt::from_clap`, just add a `&` before the argument. ### Fail if attributes are not used by [@TeXitoi](https://github.com/TeXitoi) StructOpt was quite fuzzy in its attribute parsing: it was only searching for interresting things, e. g. something like `#[structopt(foo(bar))]` was accepted but not used. It now fails the compilation. You should have nothing to do here. This breaking change may highlight some missuse that can be bugs. In future versions, if there is cases that are not highlighed, they will be considerated as bugs, not breaking changes. ### Use `raw()` wrapping instead of `_raw` suffixing by [@TeXitoi](https://github.com/TeXitoi) The syntax of raw attributes is changed to improve the syntax. You have to change `foo_raw = "bar", baz_raw = "foo"` by `raw(foo = "bar", baz = "foo")` or `raw(foo = "bar"), raw(baz = "foo")`. ## New features * Add `parse(from_occurrences)` parser by [@SergioBenitez](https://github.com/SergioBenitez) * Support 1-uple enum variant as subcommand by [@TeXitoi](https://github.com/TeXitoi) * structopt-derive crate is now an implementation detail, structopt reexport the custom derive macro by [@TeXitoi](https://github.com/TeXitoi) * Add the `StructOpt::from_iter` method by [@Kerollmops](https://github.com/Kerollmops) ## Documentation * Improve doc by [@bestouff](https://github.com/bestouff) * All the documentation is now on the structopt crate by [@TeXitoi](https://github.com/TeXitoi) # v0.1.7 (2018-01-23) * Allow opting out of clap default features by [@ski-csis](https://github.com/ski-csis) # v0.1.6 (2017-11-25) * Improve documentation by [@TeXitoi](https://github.com/TeXitoi) * Fix bug [#31](https://github.com/TeXitoi/structopt/issues/31) by [@TeXitoi](https://github.com/TeXitoi) # v0.1.5 (2017-11-14) * Fix a bug with optional subsubcommand and Enum by [@TeXitoi](https://github.com/TeXitoi) # v0.1.4 (2017-11-09) * Implement custom string parser from either `&str` or `&OsStr` by [@kennytm](https://github.com/kennytm) # v0.1.3 (2017-11-01) * Improve doc by [@TeXitoi](https://github.com/TeXitoi) # v0.1.2 (2017-11-01) * Fix bugs [#24](https://github.com/TeXitoi/structopt/issues/24) and [#25](https://github.com/TeXitoi/structopt/issues/25) by [@TeXitoi](https://github.com/TeXitoi) * Support of methods with something else that a string as argument thanks to `_raw` suffix by [@Flakebi](https://github.com/Flakebi) # v0.1.1 (2017-09-22) * Better formating of multiple authors by [@killercup](https://github.com/killercup) # v0.1.0 (2017-07-17) * Subcommand support by [@williamyaoh](https://github.com/williamyaoh) # v0.0.5 (2017-06-16) * Using doc comment to populate help by [@killercup](https://github.com/killercup) # v0.0.3 (2017-02-11) * First version with flags, arguments and options support by [@TeXitoi](https://github.com/TeXitoi) structopt-0.3.26/Cargo.lock0000644000000327060000000000100111560ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 [[package]] name = "ansi_term" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" dependencies = [ "winapi", ] [[package]] name = "arrayref" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" [[package]] name = "arrayvec" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" [[package]] name = "atty" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi", "libc", "winapi", ] [[package]] name = "autocfg" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "base64" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" [[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "blake2b_simd" version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" dependencies = [ "arrayref", "arrayvec", "constant_time_eq", ] [[package]] name = "byteorder" version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b" [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" version = "2.33.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" dependencies = [ "ansi_term", "atty", "bitflags", "clippy", "strsim", "term_size", "textwrap", "unicode-width", "vec_map", "yaml-rust", ] [[package]] name = "clippy" version = "0.0.302" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d911ee15579a3f50880d8c1d59ef6e79f9533127a3bd342462f5d584f5e8c294" dependencies = [ "term", ] [[package]] name = "constant_time_eq" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" [[package]] name = "crossbeam-utils" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49" dependencies = [ "autocfg", "cfg-if", "lazy_static", ] [[package]] name = "dirs" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" dependencies = [ "libc", "redox_users", "winapi", ] [[package]] name = "dissimilar" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc4b29f4b9bb94bf267d57269fd0706d343a160937108e9619fe380645428abb" [[package]] name = "getrandom" version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ "cfg-if", "libc", "wasi", ] [[package]] name = "glob" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "heck" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac" dependencies = [ "unicode-segmentation", ] [[package]] name = "hermit-abi" version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" dependencies = [ "libc", ] [[package]] name = "itoa" version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "265d751d31d6780a3f956bb5b8022feba2d94eeee5a84ba64f4212eedca42213" [[package]] name = "paw" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09c0fc9b564dbc3dc2ed7c92c0c144f4de340aa94514ce2b446065417c4084e9" dependencies = [ "paw-attributes", "paw-raw", ] [[package]] name = "paw-attributes" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f35583365be5d148e959284f42526841917b7bfa09e2d1a7ad5dde2cf0eaa39" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "paw-raw" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f0b59668fe80c5afe998f0c0bf93322bf2cd66cafeeb80581f291716f3467f2" [[package]] name = "proc-macro-error" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", "syn", "version_check", ] [[package]] name = "proc-macro-error-attr" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ "proc-macro2", "quote", "version_check", ] [[package]] name = "proc-macro2" version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" dependencies = [ "unicode-xid", ] [[package]] name = "quote" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" dependencies = [ "proc-macro2", ] [[package]] name = "redox_syscall" version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "redox_users" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" dependencies = [ "getrandom", "redox_syscall", "rust-argon2", ] [[package]] name = "rust-argon2" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb" dependencies = [ "base64", "blake2b_simd", "constant_time_eq", "crossbeam-utils", ] [[package]] name = "rustversion" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb5d2a036dc6d2d8fd16fde3498b04306e29bd193bf306a57427019b823d5acd" [[package]] name = "ryu" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" version = "1.0.123" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.123" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "serde_json" version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" dependencies = [ "itoa", "ryu", "serde", ] [[package]] name = "strsim" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "structopt" version = "0.3.26" dependencies = [ "clap", "lazy_static", "paw", "rustversion", "structopt-derive", "strum", "trybuild", ] [[package]] name = "structopt-derive" version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" dependencies = [ "heck", "proc-macro-error", "proc-macro2", "quote", "syn", ] [[package]] name = "strum" version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aaf86bbcfd1fa9670b7a129f64fc0c9fcbbfe4f1bc4210e9e98fe71ffc12cde2" dependencies = [ "strum_macros", ] [[package]] name = "strum_macros" version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d06aaeeee809dbc59eb4556183dd927df67db1540de5be8d3ec0b6636358a5ec" dependencies = [ "heck", "proc-macro2", "quote", "syn", ] [[package]] name = "syn" version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed22b90a0e734a23a7610f4283ac9e5acfb96cbb30dfefa540d66f866f1c09c5" dependencies = [ "proc-macro2", "quote", "unicode-xid", ] [[package]] name = "term" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42" dependencies = [ "byteorder", "dirs", "winapi", ] [[package]] name = "term_size" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9" dependencies = [ "libc", "winapi", ] [[package]] name = "termcolor" version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" dependencies = [ "winapi-util", ] [[package]] name = "textwrap" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" dependencies = [ "term_size", "unicode-width", ] [[package]] name = "toml" version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" dependencies = [ "serde", ] [[package]] name = "trybuild" version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99471a206425fba51842a9186315f32d91c56eadc21ea4c21f847b59cf778f8b" dependencies = [ "dissimilar", "glob", "lazy_static", "serde", "serde_json", "termcolor", "toml", ] [[package]] name = "unicode-segmentation" version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796" [[package]] name = "unicode-width" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" [[package]] name = "unicode-xid" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" [[package]] name = "vec_map" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "winapi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ "winapi-i686-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu", ] [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ "winapi", ] [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "yaml-rust" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992" structopt-0.3.26/Cargo.toml0000644000000031460000000000100111750ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2018" name = "structopt" version = "0.3.26" authors = ["Guillaume Pinot ", "others"] description = "Parse command line argument by defining a struct." documentation = "https://docs.rs/structopt" readme = "README.md" keywords = ["clap", "cli", "derive", "docopt"] categories = ["command-line-interface"] license = "Apache-2.0 OR MIT" repository = "https://github.com/TeXitoi/structopt" [dependencies.clap] version = "2.33" default-features = false [dependencies.lazy_static] version = "1.4.0" [dependencies.paw_dep] version = "1" optional = true package = "paw" [dependencies.structopt-derive] version = "=0.4.18" [dev-dependencies.rustversion] version = "1" [dev-dependencies.strum] version = "0.21" features = ["derive"] [dev-dependencies.trybuild] version = "1.0.5" features = ["diff"] [features] color = ["clap/color"] debug = ["clap/debug"] default = ["clap/default"] doc = ["clap/doc"] lints = ["clap/lints"] no_cargo = ["clap/no_cargo"] paw = ["structopt-derive/paw", "paw_dep"] suggestions = ["clap/suggestions"] wrap_help = ["clap/wrap_help"] yaml = ["clap/yaml"] [badges.travis-ci] repository = "TeXitoi/structopt" structopt-0.3.26/Cargo.toml.orig000064400000000000000000000021620072674642500147030ustar 00000000000000[package] name = "structopt" version = "0.3.26" edition = "2018" authors = ["Guillaume Pinot ", "others"] description = "Parse command line argument by defining a struct." documentation = "https://docs.rs/structopt" repository = "https://github.com/TeXitoi/structopt" keywords = ["clap", "cli", "derive", "docopt"] categories = ["command-line-interface"] license = "Apache-2.0 OR MIT" readme = "README.md" [features] default = ["clap/default"] suggestions = ["clap/suggestions"] color = ["clap/color"] wrap_help = ["clap/wrap_help"] yaml = ["clap/yaml"] lints = ["clap/lints"] debug = ["clap/debug"] no_cargo = ["clap/no_cargo"] doc = ["clap/doc"] paw = ["structopt-derive/paw", "paw_dep"] [badges] travis-ci = { repository = "TeXitoi/structopt" } [dependencies] clap = { version = "2.33", default-features = false } structopt-derive = { path = "structopt-derive", version = "=0.4.18" } lazy_static = "1.4.0" paw_dep = { version = "1", optional = true, package = "paw" } [dev-dependencies] trybuild = { version = "1.0.5", features = ["diff"] } rustversion = "1" strum = { version = "0.21", features = ["derive"] } structopt-0.3.26/LICENSE-APACHE000064400000000000000000000261350072674642500137460ustar 00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. structopt-0.3.26/LICENSE-MIT000064400000000000000000000021200072674642500134420ustar 00000000000000MIT License Copyright (c) 2018 Guillaume Pinot (@TeXitoi) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. structopt-0.3.26/README.md000064400000000000000000000112410072674642500132710ustar 00000000000000# StructOpt [![Build status](https://travis-ci.com/TeXitoi/structopt.svg?branch=master)](https://app.travis-ci.com/github/TeXitoi/structopt) [![](https://img.shields.io/crates/v/structopt.svg)](https://crates.io/crates/structopt) [![](https://docs.rs/structopt/badge.svg)](https://docs.rs/structopt) [![unsafe forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance/) Parse command line arguments by defining a struct. It combines [clap](https://crates.io/crates/clap) with custom derive. ## Maintenance As clap v3 is now out, and the structopt features are integrated into (almost as-is), structopt is now in maintenance mode: no new feature will be added. Bugs will be fixed, and documentation improvements will be accepted. ## Documentation Find it on [Docs.rs](https://docs.rs/structopt). You can also check the [examples](https://github.com/TeXitoi/structopt/tree/master/examples) and the [changelog](https://github.com/TeXitoi/structopt/blob/master/CHANGELOG.md). ## Example Add `structopt` to your dependencies of your `Cargo.toml`: ```toml [dependencies] structopt = "0.3" ``` And then, in your rust file: ```rust use std::path::PathBuf; use structopt::StructOpt; /// A basic example #[derive(StructOpt, Debug)] #[structopt(name = "basic")] struct Opt { // A flag, true if used in the command line. Note doc comment will // be used for the help message of the flag. The name of the // argument will be, by default, based on the name of the field. /// Activate debug mode #[structopt(short, long)] debug: bool, // The number of occurrences of the `v/verbose` flag /// Verbose mode (-v, -vv, -vvv, etc.) #[structopt(short, long, parse(from_occurrences))] verbose: u8, /// Set speed #[structopt(short, long, default_value = "42")] speed: f64, /// Output file #[structopt(short, long, parse(from_os_str))] output: PathBuf, // the long option will be translated by default to kebab case, // i.e. `--nb-cars`. /// Number of cars #[structopt(short = "c", long)] nb_cars: Option, /// admin_level to consider #[structopt(short, long)] level: Vec, /// Files to process #[structopt(name = "FILE", parse(from_os_str))] files: Vec, } fn main() { let opt = Opt::from_args(); println!("{:#?}", opt); } ``` Using this example: ``` $ ./basic error: The following required arguments were not provided: --output USAGE: basic --output --speed For more information try --help $ ./basic --help basic 0.3.0 Guillaume Pinot , others A basic example USAGE: basic [FLAGS] [OPTIONS] --output [--] [file]... FLAGS: -d, --debug Activate debug mode -h, --help Prints help information -V, --version Prints version information -v, --verbose Verbose mode (-v, -vv, -vvv, etc.) OPTIONS: -l, --level ... admin_level to consider -c, --nb-cars Number of cars -o, --output Output file -s, --speed Set speed [default: 42] ARGS: ... Files to process $ ./basic -o foo.txt Opt { debug: false, verbose: 0, speed: 42.0, output: "foo.txt", nb_cars: None, level: [], files: [], } $ ./basic -o foo.txt -dvvvs 1337 -l alice -l bob --nb-cars 4 bar.txt baz.txt Opt { debug: true, verbose: 3, speed: 1337.0, output: "foo.txt", nb_cars: Some( 4, ), level: [ "alice", "bob", ], files: [ "bar.txt", "baz.txt", ], } ``` ## StructOpt rustc version policy - Minimum rustc version modification must be specified in the [changelog](https://github.com/TeXitoi/structopt/blob/master/CHANGELOG.md) and in the [travis configuration](https://github.com/TeXitoi/structopt/blob/master/.travis.yml). - Contributors can increment minimum rustc version without any justification if the new version is required by the latest version of one of StructOpt's dependencies (`cargo update` will not fail on StructOpt). - Contributors can increment minimum rustc version if the library user experience is improved. ## License Licensed under either of - Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or ) - MIT license ([LICENSE-MIT](LICENSE-MIT) or ) at your option. ### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. structopt-0.3.26/examples/README.md000064400000000000000000000036720072674642500151200ustar 00000000000000# Collection of examples "how to use `structopt`" ### [Help on the bottom](after_help.rs) How to append a postscript to the help message generated. ### [At least N](at_least_two.rs) How to require presence of at least N values, like `val1 val2 ... valN ... valM`. ### [Basic](basic.rs) A basic example how to use `structopt`. ### [Deny missing docs](deny_missing_docs.rs) **This is not an example but a test**, it should be moved to `tests` folder as soon as [this](https://github.com/rust-lang/rust/issues/24584) is fixed (if ever). ### [Doc comments](doc_comments.rs) How to use doc comments in place of `help/long_help`. ### [Enums as arguments](enum_in_args.rs) How to use `arg_enum!` with `StructOpt`. ### [Arguments of subcommands in separate `struct`](enum_tuple.rs) How to extract subcommands' args into external structs. ### [Environment variables](env.rs) How to use environment variable fallback and how it interacts with `default_value`. ### [Advanced](example.rs) Somewhat complex example of usage of `structopt`. ### [Flatten](flatten.rs) How to use `#[structopt(flatten)]` ### [`bash` completions](gen_completions.rs) Generating `bash` completions with `structopt`. ### [Git](git.rs) Pseudo-`git` example, shows how to use subcommands and how to document them. ### [Groups](group.rs) Using `clap::Arg::group` with `structopt`. ### [`key=value` pairs](keyvalue.rs) How to parse `key=value` pairs. ### [`--no-*` flags](negative_flag.rs) How to add `no-thing` flag which is `true` by default and `false` if passed. ### [No version](no_version.rs) How to completely remove version. ### [Rename all](rename_all.rs) How `#[structopt(rename_all)]` works. ### [Required If](required_if.rs) How to use `#[structopt(required_if)]`. ### [Skip](skip.rs) How to use `#[structopt(skip)]`. ### [Aliases](subcommand_aliases.rs) How to use aliases ### [`true` or `false`](true_or_false.rs) How to express "`"true"` or `"false"` argument. structopt-0.3.26/examples/after_help.rs000064400000000000000000000016660072674642500163210ustar 00000000000000//! How to append a postscript to the help message generated. //! //! Running this example with --help prints this message: //! ----------------------------------------------------- //! structopt 0.3.25 //! I am a program and I do things. //! //! Sometimes they even work. //! //! USAGE: //! after_help [FLAGS] //! //! FLAGS: //! -d //! Release the dragon //! //! -h, --help //! Prints help information //! //! -V, --version //! Prints version information //! //! //! Beware `-d`, dragons be here //! ----------------------------------------------------- use structopt::StructOpt; /// I am a program and I do things. /// /// Sometimes they even work. #[derive(StructOpt, Debug)] #[structopt(after_help = "Beware `-d`, dragons be here")] struct Opt { /// Release the dragon. #[structopt(short)] dragon: bool, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/examples/at_least_two.rs000064400000000000000000000012750072674642500166710ustar 00000000000000//! How to require presence of at least N values, //! like `val1 val2 ... valN ... valM`. //! //! Running this example with --help prints this message: //! ----------------------------------------------------- //! structopt 0.3.25 //! //! USAGE: //! at_least_two ... //! //! FLAGS: //! -h, --help Prints help information //! -V, --version Prints version information //! //! ARGS: //! ... //! ----------------------------------------------------- use structopt::StructOpt; #[derive(StructOpt, Debug)] struct Opt { #[structopt(required = true, min_values = 2)] foos: Vec, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/examples/basic.rs000064400000000000000000000040540072674642500152630ustar 00000000000000//! A somewhat comprehensive example of a typical `StructOpt` usage.use //! //! Running this example with --help prints this message: //! ----------------------------------------------------- //! basic 0.3.25 //! A basic example //! //! USAGE: //! basic [FLAGS] [OPTIONS] --output [--] [FILE]... //! //! FLAGS: //! -d, --debug Activate debug mode //! -h, --help Prints help information //! -V, --version Prints version information //! -v, --verbose Verbose mode (-v, -vv, -vvv, etc.) //! //! OPTIONS: //! -l, --level ... admin_level to consider //! -c, --nb-cars Number of cars //! -o, --output Output file //! -s, --speed Set speed [default: 42] //! //! ARGS: //! ... Files to process //! ----------------------------------------------------- use std::path::PathBuf; use structopt::StructOpt; /// A basic example #[derive(StructOpt, Debug)] #[structopt(name = "basic")] struct Opt { // A flag, true if used in the command line. Note doc comment will // be used for the help message of the flag. The name of the // argument will be, by default, based on the name of the field. /// Activate debug mode #[structopt(short, long)] debug: bool, // The number of occurrences of the `v/verbose` flag /// Verbose mode (-v, -vv, -vvv, etc.) #[structopt(short, long, parse(from_occurrences))] verbose: u8, /// Set speed #[structopt(short, long, default_value = "42")] speed: f64, /// Output file #[structopt(short, long, parse(from_os_str))] output: PathBuf, // the long option will be translated by default to kebab case, // i.e. `--nb-cars`. /// Number of cars #[structopt(short = "c", long)] nb_cars: Option, /// admin_level to consider #[structopt(short, long)] level: Vec, /// Files to process #[structopt(name = "FILE", parse(from_os_str))] files: Vec, } fn main() { let opt = Opt::from_args(); println!("{:#?}", opt); } structopt-0.3.26/examples/deny_missing_docs.rs000064400000000000000000000033460072674642500177050ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. // This should be in tests but it will not work until // https://github.com/rust-lang/rust/issues/24584 is fixed //! A test to check that structopt compiles with deny(missing_docs) //! //! Running this example with --help prints this message: //! ----------------------------------------------------- //! structopt 0.3.25 //! Some subcommands //! //! USAGE: //! deny_missing_docs [FLAGS] [SUBCOMMAND] //! //! FLAGS: //! -h, --help Prints help information //! -V, --version Prints version information //! -v //! //! SUBCOMMANDS: //! a command A //! b command B //! c command C //! help Prints this message or the help of the given subcommand(s) //! ----------------------------------------------------- #![deny(missing_docs)] use structopt::StructOpt; /// The options #[derive(StructOpt, Debug, PartialEq)] pub struct Opt { #[structopt(short)] verbose: bool, #[structopt(subcommand)] cmd: Option, } /// Some subcommands #[derive(StructOpt, Debug, PartialEq)] pub enum Cmd { /// command A A, /// command B B { /// Alice? #[structopt(short)] alice: bool, }, /// command C C(COpt), } /// The options for C #[derive(StructOpt, Debug, PartialEq)] pub struct COpt { #[structopt(short)] bob: bool, } fn main() { println!("{:?}", Opt::from_args()); } structopt-0.3.26/examples/doc_comments.rs000064400000000000000000000103560072674642500166560ustar 00000000000000//! How to use doc comments in place of `help/long_help`. //! //! Running this example with --help prints this message: //! ----------------------------------------------------- //! basic 0.3.25 //! A basic example for the usage of doc comments as replacement of the arguments `help`, `long_help`, `about` and //! `long_about` //! //! USAGE: //! doc_comments [FLAGS] //! //! FLAGS: //! -f, --first-flag //! Just use doc comments to replace `help`, `long_help`, `about` or `long_about` input //! //! -h, --help //! Prints help information //! //! -s, --second-flag //! Split between `help` and `long_help`. //! //! In the previous case structopt is going to present the whole comment both as text for the `help` and the //! `long_help` argument. //! //! But if the doc comment is formatted like this example -- with an empty second line splitting the heading and //! the rest of the comment -- only the first line is used as `help` argument. The `long_help` argument will //! still contain the whole comment. //! //! ## Attention //! //! Any formatting next to empty lines that could be used inside a doc comment is currently not preserved. If //! lists or other well formatted content is required it is necessary to use the related structopt argument with //! a raw string as shown on the `third_flag` description. //! -t, --third-flag //! This is a raw string. //! //! It can be used to pass well formatted content (e.g. lists or source //! code) in the description: //! //! - first example list entry //! - second example list entry //! //! -V, --version //! Prints version information //! //! //! SUBCOMMANDS: //! first The same rules described previously for flags. Are also true for in regards of sub-commands //! help Prints this message or the help of the given subcommand(s) //! second Applicable for both `about` an `help` //! ----------------------------------------------------- use structopt::StructOpt; /// A basic example for the usage of doc comments as replacement /// of the arguments `help`, `long_help`, `about` and `long_about`. #[derive(StructOpt, Debug)] #[structopt(name = "basic")] struct Opt { /// Just use doc comments to replace `help`, `long_help`, /// `about` or `long_about` input. #[structopt(short, long)] first_flag: bool, /// Split between `help` and `long_help`. /// /// In the previous case structopt is going to present /// the whole comment both as text for the `help` and the /// `long_help` argument. /// /// But if the doc comment is formatted like this example /// -- with an empty second line splitting the heading and /// the rest of the comment -- only the first line is used /// as `help` argument. The `long_help` argument will still /// contain the whole comment. /// /// ## Attention /// /// Any formatting next to empty lines that could be used /// inside a doc comment is currently not preserved. If /// lists or other well formatted content is required it is /// necessary to use the related structopt argument with a /// raw string as shown on the `third_flag` description. #[structopt(short, long)] second_flag: bool, #[structopt( short, long, long_help = r"This is a raw string. It can be used to pass well formatted content (e.g. lists or source code) in the description: - first example list entry - second example list entry " )] third_flag: bool, #[structopt(subcommand)] sub_command: SubCommand, } #[derive(StructOpt, Debug)] #[structopt()] enum SubCommand { /// The same rules described previously for flags. Are /// also true for in regards of sub-commands. First, /// Applicable for both `about` an `help`. /// /// The formatting rules described in the comment of the /// `second_flag` also apply to the description of /// sub-commands which is normally given through the `about` /// and `long_about` arguments. Second, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/examples/enum_in_args.rs000064400000000000000000000015410072674642500166460ustar 00000000000000//! How to use `arg_enum!` with `StructOpt`. //! //! Running this example with --help prints this message: //! ----------------------------------------------------- //! structopt 0.3.25 //! //! USAGE: //! enum_in_args //! //! FLAGS: //! -h, --help Prints help information //! -V, --version Prints version information //! //! ARGS: //! Important argument [possible values: Foo, Bar, FooBar] //! ----------------------------------------------------- use clap::arg_enum; use structopt::StructOpt; arg_enum! { #[derive(Debug)] enum Baz { Foo, Bar, FooBar } } #[derive(StructOpt, Debug)] struct Opt { /// Important argument. #[structopt(possible_values = &Baz::variants(), case_insensitive = true)] i: Baz, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/examples/enum_in_args_with_strum.rs000064400000000000000000000017260072674642500211400ustar 00000000000000//! Running this example with --help prints this message: //! ----------------------------------------------------- //! structopt 0.3.25 //! //! USAGE: //! enum_in_args_with_strum [OPTIONS] //! //! FLAGS: //! -h, --help Prints help information //! -V, --version Prints version information //! //! OPTIONS: //! --format [default: txt] [possible values: txt, md, html] //! ----------------------------------------------------- use structopt::StructOpt; use strum::{EnumString, EnumVariantNames, VariantNames}; const DEFAULT: &str = "txt"; #[derive(StructOpt, Debug)] struct Opt { #[structopt( long, possible_values = Format::VARIANTS, case_insensitive = true, default_value = DEFAULT, )] format: Format, } #[derive(EnumString, EnumVariantNames, Debug)] #[strum(serialize_all = "kebab_case")] enum Format { Txt, Md, Html, } fn main() { println!("{:?}", Opt::from_args()); } structopt-0.3.26/examples/enum_tuple.rs000064400000000000000000000017130072674642500163560ustar 00000000000000//! How to extract subcommands' args into external structs. //! //! Running this example with --help prints this message: //! ----------------------------------------------------- //! classify 0.3.25 //! //! USAGE: //! enum_tuple //! //! FLAGS: //! -h, --help Prints help information //! -V, --version Prints version information //! //! SUBCOMMANDS: //! foo //! help Prints this message or the help of the given subcommand(s) //! ----------------------------------------------------- use structopt::StructOpt; #[derive(Debug, StructOpt)] pub struct Foo { pub bar: Option, } #[derive(Debug, StructOpt)] pub enum Command { #[structopt(name = "foo")] Foo(Foo), } #[derive(Debug, StructOpt)] #[structopt(name = "classify")] pub struct ApplicationArguments { #[structopt(subcommand)] pub command: Command, } fn main() { let opt = ApplicationArguments::from_args(); println!("{:?}", opt); } structopt-0.3.26/examples/env.rs000064400000000000000000000025410072674642500147710ustar 00000000000000//! How to use environment variable fallback an how it //! interacts with `default_value`. //! //! Running this example with --help prints this message: //! ----------------------------------------------------- //! env 0.3.25 //! Example for allowing to specify options via environment variables //! //! USAGE: //! env [OPTIONS] --api-url //! //! FLAGS: //! -h, --help Prints help information //! -V, --version Prints version information //! //! OPTIONS: //! --api-url URL for the API server [env: API_URL=] //! --retries Number of retries [env: RETRIES=] [default: 5] //! ----------------------------------------------------- use structopt::StructOpt; /// Example for allowing to specify options via environment variables. #[derive(StructOpt, Debug)] #[structopt(name = "env")] struct Opt { // Use `env` to enable specifying the option with an environment // variable. Command line arguments take precedence over env. /// URL for the API server #[structopt(long, env = "API_URL")] api_url: String, // The default value is used if neither argument nor environment // variable is specified. /// Number of retries #[structopt(long, env = "RETRIES", default_value = "5")] retries: u32, } fn main() { let opt = Opt::from_args(); println!("{:#?}", opt); } structopt-0.3.26/examples/example.rs000064400000000000000000000046440072674642500156420ustar 00000000000000//! Somewhat complex example of usage of structopt. //! //! Running this example with --help prints this message: //! ----------------------------------------------------- //! example 0.3.25 //! An example of StructOpt usage //! //! USAGE: //! example [FLAGS] [OPTIONS] [--] [output] //! //! FLAGS: //! -d, --debug Activate debug mode //! -h, --help Prints help information //! -V, --version Prints version information //! //! OPTIONS: //! --log Log file, stdout if no file, no logging if not present //! --optv ... //! -s, --speed Set speed [default: 42] //! //! ARGS: //! Input file //! Output file, stdout if not present //! ----------------------------------------------------- use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "example")] /// An example of StructOpt usage. struct Opt { // A flag, true if used in the command line. #[structopt(short, long)] /// Activate debug mode debug: bool, // An argument of type float, with a default value. #[structopt(short, long, default_value = "42")] /// Set speed speed: f64, // Needed parameter, the first on the command line. /// Input file input: String, // An optional parameter, will be `None` if not present on the // command line. /// Output file, stdout if not present output: Option, // An optional parameter with optional value, will be `None` if // not present on the command line, will be `Some(None)` if no // argument is provided (i.e. `--log`) and will be // `Some(Some(String))` if argument is provided (e.g. `--log // log.txt`). #[structopt(long)] #[allow(clippy::option_option)] /// Log file, stdout if no file, no logging if not present log: Option>, // An optional list of values, will be `None` if not present on // the command line, will be `Some(vec![])` if no argument is // provided (i.e. `--optv`) and will be `Some(Vec)` if // argument list is provided (e.g. `--optv a b c`). #[structopt(long)] optv: Option>, // Skipped option: it won't be parsed and will be filled with the // default value for its type (in this case it'll be an empty string). #[structopt(skip)] skipped: String, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/examples/flatten.rs000064400000000000000000000017470072674642500156450ustar 00000000000000//! How to use flattening. //! //! Running this example with --help prints this message: //! ----------------------------------------------------- //! structopt 0.3.25 //! //! USAGE: //! flatten [FLAGS] -g -u //! //! FLAGS: //! -h, --help Prints help information //! -V, --version Prints version information //! -v switch verbosity on //! //! OPTIONS: //! -g daemon group //! -u daemon user //! ----------------------------------------------------- use structopt::StructOpt; #[derive(StructOpt, Debug)] struct Cmdline { /// switch verbosity on #[structopt(short)] verbose: bool, #[structopt(flatten)] daemon_opts: DaemonOpts, } #[derive(StructOpt, Debug)] struct DaemonOpts { /// daemon user #[structopt(short)] user: String, /// daemon group #[structopt(short)] group: String, } fn main() { let opt = Cmdline::from_args(); println!("{:?}", opt); } structopt-0.3.26/examples/gen_completions.rs000064400000000000000000000023710072674642500173670ustar 00000000000000// Copyright 2019-present structopt developers // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. //! Running this example with --help prints this message: //! ----------------------------------------------------- //! structopt 0.3.25 //! An example of how to generate bash completions with structopt //! //! USAGE: //! gen_completions [FLAGS] //! //! FLAGS: //! -d, --debug Activate debug mode //! -h, --help Prints help information //! -V, --version Prints version information //! ----------------------------------------------------- use structopt::clap::Shell; use structopt::StructOpt; #[derive(StructOpt, Debug)] /// An example of how to generate bash completions with structopt. struct Opt { #[structopt(short, long)] /// Activate debug mode debug: bool, } fn main() { // generate `bash` completions in "target" directory Opt::clap().gen_completions(env!("CARGO_PKG_NAME"), Shell::Bash, "target"); let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/examples/git.rs000064400000000000000000000026200072674642500147620ustar 00000000000000//! `git.rs` serves as a demonstration of how to use subcommands, //! as well as a demonstration of adding documentation to subcommands. //! Documentation can be added either through doc comments or //! `help`/`about` attributes. //! //! Running this example with --help prints this message: //! ----------------------------------------------------- //! git 0.3.25 //! the stupid content tracker //! //! USAGE: //! git //! //! FLAGS: //! -h, --help Prints help information //! -V, --version Prints version information //! //! SUBCOMMANDS: //! add //! fetch fetch branches from remote repository //! help Prints this message or the help of the given subcommand(s) //! ----------------------------------------------------- use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "git")] /// the stupid content tracker enum Opt { /// fetch branches from remote repository Fetch { #[structopt(long)] dry_run: bool, #[structopt(long)] all: bool, #[structopt(default_value = "origin")] repository: String, }, #[structopt(help = "add files to the staging area")] Add { #[structopt(short)] interactive: bool, #[structopt(short)] all: bool, files: Vec, }, } fn main() { let matches = Opt::from_args(); println!("{:?}", matches); } structopt-0.3.26/examples/group.rs000064400000000000000000000025460072674642500153420ustar 00000000000000//! How to use `clap::Arg::group` //! //! Running this example with --help prints this message: //! ----------------------------------------------------- //! structopt 0.3.25 //! //! USAGE: //! group [OPTIONS] <--method |--get|--head|--post|--put|--delete> //! //! FLAGS: //! --delete HTTP DELETE //! --get HTTP GET //! -h, --help Prints help information //! --head HTTP HEAD //! --post HTTP POST //! --put HTTP PUT //! -V, --version Prints version information //! //! OPTIONS: //! --method Set a custom HTTP verb //! ----------------------------------------------------- use structopt::{clap::ArgGroup, StructOpt}; #[derive(StructOpt, Debug)] #[structopt(group = ArgGroup::with_name("verb").required(true))] struct Opt { /// Set a custom HTTP verb #[structopt(long, group = "verb")] method: Option, /// HTTP GET #[structopt(long, group = "verb")] get: bool, /// HTTP HEAD #[structopt(long, group = "verb")] head: bool, /// HTTP POST #[structopt(long, group = "verb")] post: bool, /// HTTP PUT #[structopt(long, group = "verb")] put: bool, /// HTTP DELETE #[structopt(long, group = "verb")] delete: bool, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/examples/keyvalue.rs000064400000000000000000000026740072674642500160350ustar 00000000000000//! How to parse "key=value" pairs with structopt. //! //! Running this example with --help prints this message: //! ----------------------------------------------------- //! structopt 0.3.25 //! //! USAGE: //! keyvalue [OPTIONS] //! //! FLAGS: //! -h, --help Prints help information //! -V, --version Prints version information //! //! OPTIONS: //! -D ... //! ----------------------------------------------------- use std::error::Error; use structopt::StructOpt; /// Parse a single key-value pair fn parse_key_val(s: &str) -> Result<(T, U), Box> where T: std::str::FromStr, T::Err: Error + 'static, U: std::str::FromStr, U::Err: Error + 'static, { let pos = s .find('=') .ok_or_else(|| format!("invalid KEY=value: no `=` found in `{}`", s))?; Ok((s[..pos].parse()?, s[pos + 1..].parse()?)) } #[derive(StructOpt, Debug)] struct Opt { // number_of_values = 1 forces the user to repeat the -D option for each key-value pair: // my_program -D a=1 -D b=2 // Without number_of_values = 1 you can do: // my_program -D a=1 b=2 // but this makes adding an argument after the values impossible: // my_program -D a=1 -D b=2 my_input_file // becomes invalid. #[structopt(short = "D", parse(try_from_str = parse_key_val), number_of_values = 1)] defines: Vec<(String, i32)>, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/examples/negative_flag.rs000064400000000000000000000013160072674642500167730ustar 00000000000000//! How to add `no-thing` flag which is `true` by default and //! `false` if passed. //! //! Running this example with --help prints this message: //! ----------------------------------------------------- //! structopt 0.3.25 //! //! USAGE: //! negative_flag [FLAGS] //! //! FLAGS: //! -h, --help Prints help information //! -V, --version Prints version information //! --no-verbose //! ----------------------------------------------------- use structopt::StructOpt; #[derive(Debug, StructOpt)] struct Opt { #[structopt(long = "no-verbose", parse(from_flag = std::ops::Not::not))] verbose: bool, } fn main() { let cmd = Opt::from_args(); println!("{:#?}", cmd); } structopt-0.3.26/examples/no_version.rs000064400000000000000000000011460072674642500163620ustar 00000000000000//! How to completely remove version. //! //! Running this example with --help prints this message: //! ----------------------------------------------------- //! no_version //! //! USAGE: //! no_version //! //! FLAGS: //! -h, --help Prints help information //! ----------------------------------------------------- use structopt::clap::AppSettings; use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt( name = "no_version", no_version, global_settings = &[AppSettings::DisableVersion] )] struct Opt {} fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/examples/rename_all.rs000064400000000000000000000064670072674642500163130ustar 00000000000000//! Example on how the `rename_all` parameter works. //! //! `rename_all` can be used to override the casing style used during argument //! generation. By default the `kebab-case` style will be used but there are a wide //! variety of other styles available. //! //! ## Supported styles overview: //! //! - **Camel Case**: Indicate word boundaries with uppercase letter, excluding //! the first word. //! - **Kebab Case**: Keep all letters lowercase and indicate word boundaries //! with hyphens. //! - **Pascal Case**: Indicate word boundaries with uppercase letter, //! including the first word. //! - **Screaming Snake Case**: Keep all letters uppercase and indicate word //! boundaries with underscores. //! - **Snake Case**: Keep all letters lowercase and indicate word boundaries //! with underscores. //! - **Verbatim**: Use the original attribute name defined in the code. //! //! - **Lower Case**: Keep all letters lowercase and remove word boundaries. //! //! - **Upper Case**: Keep all letters uppercase and remove word boundaries. //! //! Running this example with --help prints this message: //! ----------------------------------------------------- //! rename_all 0.3.25 //! //! USAGE: //! rename_all //! //! FLAGS: //! -h, --help Prints help information //! -V, --version Prints version information //! //! SUBCOMMANDS: //! FIRST_COMMAND A screaming loud first command. Only use if necessary //! SecondCommand Not nearly as loud as the first command //! help Prints this message or the help of the given subcommand(s) //! ----------------------------------------------------- use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "rename_all", rename_all = "screaming_snake_case")] enum Opt { // This subcommand will be named `FIRST_COMMAND`. As the command doesn't // override the initial casing style, ... /// A screaming loud first command. Only use if necessary. FirstCommand { // this flag will be available as `--FOO` and `-F`. /// This flag will even scream louder. #[structopt(long, short)] foo: bool, }, // As we override the casing style for this variant the related subcommand // will be named `SecondCommand`. /// Not nearly as loud as the first command. #[structopt(rename_all = "pascal_case")] SecondCommand { // We can also override it again on a single field. /// Nice quiet flag. No one is annoyed. #[structopt(rename_all = "snake_case", long)] bar_option: bool, // Renaming will not be propagated into subcommand flagged enums. If // a non default casing style is required it must be defined on the // enum itself. #[structopt(subcommand)] cmds: Subcommands, // or flattened structs. #[structopt(flatten)] options: BonusOptions, }, } #[derive(StructOpt, Debug)] enum Subcommands { // This one will be available as `first-subcommand`. FirstSubcommand, } #[derive(StructOpt, Debug)] struct BonusOptions { // And this one will be available as `baz-option`. #[structopt(long)] baz_option: bool, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/examples/required_if.rs000064400000000000000000000032240072674642500164760ustar 00000000000000//! How to use `required_if` with structopt. //! //! Running this example with --help prints this message: //! ----------------------------------------------------- //! structopt 0.3.25 //! //! USAGE: //! required_if -o [FILE] //! //! FLAGS: //! -h, --help Prints help information //! -V, --version Prints version information //! //! OPTIONS: //! -o Where to write the output: to `stdout` or `file` //! //! ARGS: //! File name: only required when `out-type` is set to `file` //! ----------------------------------------------------- use structopt::StructOpt; #[derive(Debug, StructOpt, PartialEq)] struct Opt { /// Where to write the output: to `stdout` or `file` #[structopt(short)] out_type: String, /// File name: only required when `out-type` is set to `file` #[structopt(name = "FILE", required_if("out-type", "file"))] file_name: Option, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } #[cfg(test)] mod tests { use super::*; #[test] fn test_opt_out_type_file_without_file_name_returns_err() { let opt = Opt::from_iter_safe(&["test", "-o", "file"]); let err = opt.unwrap_err(); assert_eq!(err.kind, clap::ErrorKind::MissingRequiredArgument); } #[test] fn test_opt_out_type_file_with_file_name_returns_ok() { let opt = Opt::from_iter_safe(&["test", "-o", "file", "filename"]); let opt = opt.unwrap(); assert_eq!( opt, Opt { out_type: "file".into(), file_name: Some("filename".into()), } ); } } structopt-0.3.26/examples/skip.rs000064400000000000000000000015130072674642500151450ustar 00000000000000//! How to use `#[structopt(skip)]` use structopt::StructOpt; #[derive(StructOpt, Debug, PartialEq)] pub struct Opt { #[structopt(long, short)] number: u32, #[structopt(skip)] k: Kind, #[structopt(skip)] v: Vec, #[structopt(skip = Kind::A)] k2: Kind, #[structopt(skip = vec![1, 2, 3])] v2: Vec, #[structopt(skip = "cake")] // &str implements Into s: String, } #[derive(Debug, PartialEq)] enum Kind { A, B, } impl Default for Kind { fn default() -> Self { return Kind::B; } } fn main() { assert_eq!( Opt::from_iter(&["test", "-n", "10"]), Opt { number: 10, k: Kind::B, v: vec![], k2: Kind::A, v2: vec![1, 2, 3], s: String::from("cake") } ); } structopt-0.3.26/examples/subcommand_aliases.rs000064400000000000000000000020610072674642500200270ustar 00000000000000//! How to assign some aliases to subcommands //! //! Running this example with --help prints this message: //! ----------------------------------------------------- //! structopt 0.3.25 //! //! USAGE: //! subcommand_aliases //! //! FLAGS: //! -h, --help Prints help information //! -V, --version Prints version information //! //! SUBCOMMANDS: //! bar //! foo //! help Prints this message or the help of the given subcommand(s) //! ----------------------------------------------------- use structopt::clap::AppSettings; use structopt::StructOpt; #[derive(StructOpt, Debug)] // https://docs.rs/clap/2/clap/enum.AppSettings.html#variant.InferSubcommands #[structopt(setting = AppSettings::InferSubcommands)] enum Opt { // https://docs.rs/clap/2/clap/struct.App.html#method.alias #[structopt(alias = "foobar")] Foo, // https://docs.rs/clap/2/clap/struct.App.html#method.aliases #[structopt(aliases = &["baz", "fizz"])] Bar, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/examples/true_or_false.rs000064400000000000000000000021660072674642500170350ustar 00000000000000//! How to parse `--foo=true --bar=false` and turn them into bool. use structopt::StructOpt; fn true_or_false(s: &str) -> Result { match s { "true" => Ok(true), "false" => Ok(false), _ => Err("expected `true` or `false`"), } } #[derive(StructOpt, Debug, PartialEq)] struct Opt { // Default parser for `try_from_str` is FromStr::from_str. // `impl FromStr for bool` parses `true` or `false` so this // works as expected. #[structopt(long, parse(try_from_str))] foo: bool, // Of course, this could be done with an explicit parser function. #[structopt(long, parse(try_from_str = true_or_false))] bar: bool, // `bool` can be positional only with explicit `parse(...)` annotation #[structopt(parse(try_from_str))] boom: bool, } fn main() { assert_eq!( Opt::from_iter(&["test", "--foo=true", "--bar=false", "true"]), Opt { foo: true, bar: false, boom: true } ); // no beauty, only truth and falseness assert!(Opt::from_iter_safe(&["test", "--foo=beauty"]).is_err()); } structopt-0.3.26/link-check-headers.json000064400000000000000000000004700072674642500163300ustar 00000000000000{ "httpHeaders": [ { "urls": [ "https://", "http://" ], "headers": { "User-Agent": "broken links checker (https://github.com/TeXitoi/structopt)", "Accept": "text/html" } } ] } structopt-0.3.26/src/lib.rs000064400000000000000000001232250072674642500137230ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. #![deny(missing_docs)] #![forbid(unsafe_code)] //! This crate defines the `StructOpt` trait and its custom derive. //! //! ## Maintenance //! //! As clap v3 is now out, and the structopt features are integrated //! into (almost as-is), structopt is now in maintenance mode: no new //! feature will be added. //! //! Bugs will be fixed, and documentation improvements will be accepted. //! //! ## Features //! //! If you want to disable all the `clap` features (colors, //! suggestions, ..) add `default-features = false` to the `structopt` //! dependency: //! //! ```toml //! [dependencies] //! structopt = { version = "0.3", default-features = false } //! ``` //! //! Support for [`paw`](https://github.com/rust-cli/paw) (the //! `Command line argument paw-rser abstraction for main`) is disabled //! by default, but can be enabled in the `structopt` dependency //! with the feature `paw`: //! //! ```toml //! [dependencies] //! structopt = { version = "0.3", features = [ "paw" ] } //! paw = "1.0" //! ``` //! //! # Table of Contents //! //! - [How to `derive(StructOpt)`](#how-to-derivestructopt) //! - [Attributes](#attributes) //! - [Raw methods](#raw-methods) //! - [Magical methods](#magical-methods) //! - Arguments //! - [Type magic](#type-magic) //! - [Specifying argument types](#specifying-argument-types) //! - [Default values](#default-values) //! - [Help messages](#help-messages) //! - [Environment variable fallback](#environment-variable-fallback) //! - [Skipping fields](#skipping-fields) //! - [Subcommands](#subcommands) //! - [Optional subcommands](#optional-subcommands) //! - [External subcommands](#external-subcommands) //! - [Flattening subcommands](#flattening-subcommands) //! - [Flattening](#flattening) //! - [Custom string parsers](#custom-string-parsers) //! - [Generics](#generics) //! //! //! //! ## How to `derive(StructOpt)` //! //! First, let's look at the example: //! //! ``` //! use std::path::PathBuf; //! use structopt::StructOpt; //! //! #[derive(Debug, StructOpt)] //! #[structopt(name = "example", about = "An example of StructOpt usage.")] //! struct Opt { //! /// Activate debug mode //! // short and long flags (-d, --debug) will be deduced from the field's name //! #[structopt(short, long)] //! debug: bool, //! //! /// Set speed //! // we don't want to name it "speed", need to look smart //! #[structopt(short = "v", long = "velocity", default_value = "42")] //! speed: f64, //! //! /// Input file //! #[structopt(parse(from_os_str))] //! input: PathBuf, //! //! /// Output file, stdout if not present //! #[structopt(parse(from_os_str))] //! output: Option, //! //! /// Where to write the output: to `stdout` or `file` //! #[structopt(short)] //! out_type: String, //! //! /// File name: only required when `out-type` is set to `file` //! #[structopt(name = "FILE", required_if("out-type", "file"))] //! file_name: Option, //! } //! //! fn main() { //! # /* //! let opt = Opt::from_args(); //! # */ //! # let opt = Opt::from_iter(&["binary", "-o", "stdout", "input"]); //! println!("{:?}", opt); //! } //! ``` //! //! So `derive(StructOpt)` tells Rust to generate a command line parser, //! and the various `structopt` attributes are simply //! used for additional parameters. //! //! First, define a struct, whatever its name. This structure //! corresponds to a `clap::App`, its fields correspond to `clap::Arg` //! (unless they're [subcommands](#subcommands)), //! and you can adjust these apps and args by `#[structopt(...)]` [attributes](#attributes). //! //! **Note:** //! _________________ //! Keep in mind that `StructOpt` trait is more than just `from_args` method. //! It has a number of additional features, including access to underlying //! `clap::App` via `StructOpt::clap()`. See the //! [trait's reference documentation](trait.StructOpt.html). //! _________________ //! //! ## Attributes //! //! You can control the way `structopt` translates your struct into an actual //! [`clap::App`] invocation via `#[structopt(...)]` attributes. //! //! The attributes fall into two categories: //! - `structopt`'s own [magical methods](#magical-methods). //! //! They are used by `structopt` itself. They come mostly in //! `attr = ["whatever"]` form, but some `attr(args...)` also exist. //! //! - [`raw` attributes](#raw-methods). //! //! They represent explicit `clap::Arg/App` method calls. //! They are what used to be explicit `#[structopt(raw(...))]` attrs in pre-0.3 `structopt` //! //! Every `structopt attribute` looks like comma-separated sequence of methods: //! ``` //! # #[derive(structopt::StructOpt)] struct S { //! # //! #[structopt( //! short, // method with no arguments - always magical //! long = "--long-option", // method with one argument //! required_if("out", "file"), // method with one and more args //! parse(from_os_str = path::to::parser) // some magical methods have their own syntax //! )] //! # //! # s: () } mod path { pub(crate) mod to { pub(crate) fn parser(_: &std::ffi::OsStr) {} }} //! ``` //! //! `#[structopt(...)]` attributes can be placed on top of `struct`, `enum`, //! `struct` field or `enum` variant. Attributes on top of `struct` or `enum` //! represent `clap::App` method calls, field or variant attributes correspond //! to `clap::Arg` method calls. //! //! In other words, the `Opt` struct from the example above //! will be turned into this (*details omitted*): //! //! ``` //! # use structopt::clap::{Arg, App}; //! App::new("example") //! .version("0.2.0") //! .about("An example of StructOpt usage.") //! .arg(Arg::with_name("debug") //! .help("Activate debug mode") //! .short("debug") //! .long("debug")) //! .arg(Arg::with_name("speed") //! .help("Set speed") //! .short("v") //! .long("velocity") //! .default_value("42")) //! // and so on //! # ; //! ``` //! //! ## Raw methods //! //! They are the reason why `structopt` is so flexible. **Every and each method from //! `clap::App/Arg` can be used this way!** See the [`clap::App` //! methods](https://docs.rs/clap/2/clap/struct.App.html) and [`clap::Arg` //! methods](https://docs.rs/clap/2/clap/struct.Arg.html). //! //! ``` //! # #[derive(structopt::StructOpt)] struct S { //! # //! #[structopt( //! global = true, // name = arg form, neat for one-arg methods //! required_if("out", "file") // name(arg1, arg2, ...) form. //! )] //! # //! # s: String } //! ``` //! //! The first form can only be used for methods which take only one argument. //! The second form must be used with multi-arg methods, but can also be used with //! single-arg methods. These forms are identical otherwise. //! //! As long as `method_name` is not one of the magical methods - //! it will be translated into a mere method call. //! //! **Note:** //! _________________ //! //! "Raw methods" are direct replacement for pre-0.3 structopt's //! `#[structopt(raw(...))]` attributes, any time you would have used a `raw()` attribute //! in 0.2 you should use raw method in 0.3. //! //! Unfortunately, old raw attributes collide with `clap::Arg::raw` method. To explicitly //! warn users of this change we allow `#[structopt(raw())]` only with `true` or `false` //! literals (this method is supposed to be called only with `true` anyway). //! __________________ //! //! ## Magical methods //! //! They are the reason why `structopt` is so easy to use and convenient in most cases. //! Many of them have defaults, some of them get used even if not mentioned. //! //! Methods may be used on "top level" (on top of a `struct`, `enum` or `enum` variant) //! and/or on "field-level" (on top of a `struct` field or *inside* of an enum variant). //! Top level (non-magical) methods correspond to `App::method` calls, field-level methods //! are `Arg::method` calls. //! //! ```ignore //! #[structopt(top_level)] //! struct Foo { //! #[structopt(field_level)] //! field: u32 //! } //! //! #[structopt(top_level)] //! enum Bar { //! #[structopt(top_level)] //! Pineapple { //! #[structopt(field_level)] //! chocolate: String //! }, //! //! #[structopt(top_level)] //! Orange, //! } //! ``` //! //! - `name`: `[name = expr]` //! - On top level: `App::new(expr)`. //! //! The binary name displayed in help messages. Defaults to the crate name given by Cargo. //! //! - On field-level: `Arg::with_name(expr)`. //! //! The name for the argument the field stands for, this name appears in help messages. //! Defaults to a name, deduced from a field, see also //! [`rename_all`](#specifying-argument-types). //! //! - `version`: `[version = "version"]` //! //! Usable only on top level: `App::version("version" or env!(CARGO_PKG_VERSION))`. //! //! The version displayed in help messages. //! Defaults to the crate version given by Cargo. If `CARGO_PKG_VERSION` is not //! set no `.version()` calls will be generated unless requested. //! //! - `no_version`: `no_version` //! //! Usable only on top level. Prevents default `App::version` call, i.e //! when no `version = "version"` mentioned. //! //! - `author`: `author [= "author"]` //! //! Usable only on top level: `App::author("author" or env!(CARGO_PKG_AUTHORS))`. //! //! Author/maintainer of the binary, this name appears in help messages. //! Defaults to the crate author given by cargo, but only when `author` explicitly mentioned. //! //! - `about`: `about [= "about"]` //! //! Usable only on top level: `App::about("about" or env!(CARGO_PKG_DESCRIPTION))`. //! //! Short description of the binary, appears in help messages. //! Defaults to the crate description given by cargo, //! but only when `about` explicitly mentioned. //! //! - [`short`](#specifying-argument-types): `short [= "short-opt-name"]` //! //! Usable only on field-level. //! //! - [`long`](#specifying-argument-types): `long [= "long-opt-name"]` //! //! Usable only on field-level. //! //! - [`default_value`](#default-values): `default_value [= "default value"]` //! //! Usable only on field-level. //! //! - [`rename_all`](#specifying-argument-types): //! [`rename_all = "kebab"/"snake"/"screaming-snake"/"camel"/"pascal"/"verbatim"/"lower"/"upper"]` //! //! Usable both on top level and field level. //! //! - [`parse`](#custom-string-parsers): `parse(type [= path::to::parser::fn])` //! //! Usable only on field-level. //! //! - [`skip`](#skipping-fields): `skip [= expr]` //! //! Usable only on field-level. //! //! - [`flatten`](#flattening): `flatten` //! //! Usable on field-level or single-typed tuple variants. //! //! - [`subcommand`](#subcommands): `subcommand` //! //! Usable only on field-level. //! //! - [`external_subcommand`](#external-subcommands) //! //! Usable only on enum variants. //! //! - [`env`](#environment-variable-fallback): `env [= str_literal]` //! //! Usable only on field-level. //! //! - [`rename_all_env`](#auto-deriving-environment-variables): //! [`rename_all_env = "kebab"/"snake"/"screaming-snake"/"camel"/"pascal"/"verbatim"/"lower"/"upper"]` //! //! Usable both on top level and field level. //! //! - [`verbatim_doc_comment`](#doc-comment-preprocessing-and-structoptverbatim_doc_comment): //! `verbatim_doc_comment` //! //! Usable both on top level and field level. //! //! ## Type magic //! //! One of major things that makes `structopt` so awesome is its type magic. //! Do you want optional positional argument? Use `Option`! Or perhaps optional argument //! that optionally takes value (`[--opt=[val]]`)? Use `Option>`! //! //! Here is the table of types and `clap` methods they correspond to: //! //! Type | Effect | Added method call to `clap::Arg` //! -----------------------------|---------------------------------------------------|-------------------------------------- //! `bool` | `true` if the flag is present | `.takes_value(false).multiple(false)` //! `Option` | optional positional argument or option | `.takes_value(true).multiple(false)` //! `Option>` | optional option with optional value | `.takes_value(true).multiple(false).min_values(0).max_values(1)` //! `Vec` | list of options or the other positional arguments | `.takes_value(true).multiple(true)` //! `Option` | optional list of options | `.takes_values(true).multiple(true).min_values(0)` //! `T: FromStr` | required option or positional argument | `.takes_value(true).multiple(false).required(!has_default)` //! //! The `FromStr` trait is used to convert the argument to the given //! type, and the `Arg::validator` method is set to a method using //! `to_string()` (`FromStr::Err` must implement `std::fmt::Display`). //! If you would like to use a custom string parser other than `FromStr`, see //! the [same titled section](#custom-string-parsers) below. //! //! **Important:** //! _________________ //! Pay attention that *only literal occurrence* of this types is special, for example //! `Option` is special while `::std::option::Option` is not. //! //! If you need to avoid special casing you can make a `type` alias and //! use it in place of the said type. //! _________________ //! //! **Note:** //! _________________ //! `bool` cannot be used as positional argument unless you provide an explicit parser. //! If you need a positional bool, for example to parse `true` or `false`, you must //! annotate the field with explicit [`#[structopt(parse(...))]`](#custom-string-parsers). //! _________________ //! //! Thus, the `speed` argument is generated as: //! //! ``` //! # fn parse_validator(_: String) -> Result<(), String> { unimplemented!() } //! clap::Arg::with_name("speed") //! .takes_value(true) //! .multiple(false) //! .required(false) //! .validator(parse_validator::) //! .short("v") //! .long("velocity") //! .help("Set speed") //! .default_value("42"); //! ``` //! //! ## Specifying argument types //! //! There are three types of arguments that can be supplied to each //! (sub-)command: //! //! - short (e.g. `-h`), //! - long (e.g. `--help`) //! - and positional. //! //! Like clap, structopt defaults to creating positional arguments. //! //! If you want to generate a long argument you can specify either //! `long = $NAME`, or just `long` to get a long flag generated using //! the field name. The generated casing style can be modified using //! the `rename_all` attribute. See the `rename_all` example for more. //! //! For short arguments, `short` will use the first letter of the //! field name by default, but just like the long option it's also //! possible to use a custom letter through `short = $LETTER`. //! //! If an argument is renamed using `name = $NAME` any following call to //! `short` or `long` will use the new name. //! //! **Attention**: If these arguments are used without an explicit name //! the resulting flag is going to be renamed using `kebab-case` if the //! `rename_all` attribute was not specified previously. The same is true //! for subcommands with implicit naming through the related data structure. //! //! ``` //! use structopt::StructOpt; //! //! #[derive(StructOpt)] //! #[structopt(rename_all = "kebab-case")] //! struct Opt { //! /// This option can be specified with something like `--foo-option //! /// value` or `--foo-option=value` //! #[structopt(long)] //! foo_option: String, //! //! /// This option can be specified with something like `-b value` (but //! /// not `--bar-option value`). //! #[structopt(short)] //! bar_option: String, //! //! /// This option can be specified either `--baz value` or `-z value`. //! #[structopt(short = "z", long = "baz")] //! baz_option: String, //! //! /// This option can be specified either by `--custom value` or //! /// `-c value`. //! #[structopt(name = "custom", long, short)] //! custom_option: String, //! //! /// This option is positional, meaning it is the first unadorned string //! /// you provide (multiple others could follow). //! my_positional: String, //! //! /// This option is skipped and will be filled with the default value //! /// for its type (in this case 0). //! #[structopt(skip)] //! skipped: u32, //! } //! //! # Opt::from_iter( //! # &["test", "--foo-option", "", "-b", "", "--baz", "", "--custom", "", "positional"]); //! ``` //! //! ## Default values //! //! In clap, default values for options can be specified via [`Arg::default_value`]. //! //! Of course, you can use as a raw method: //! ``` //! # use structopt::StructOpt; //! #[derive(StructOpt)] //! struct Opt { //! #[structopt(default_value = "", long)] //! prefix: String, //! } //! ``` //! //! This is quite mundane and error-prone to type the `"..."` default by yourself, //! especially when the Rust ecosystem uses the [`Default`] trait for that. //! It would be wonderful to have `structopt` to take the `Default_default` and fill it //! for you. And yes, `structopt` can do that. //! //! Unfortunately, `default_value` takes `&str` but `Default::default` //! gives us some `Self` value. We need to map `Self` to `&str` somehow. //! //! `structopt` solves this problem via [`ToString`] trait. //! //! To be able to use auto-default the type must implement *both* `Default` and `ToString`: //! //! ``` //! # use structopt::StructOpt; //! #[derive(StructOpt)] //! struct Opt { //! // just leave the `= "..."` part and structopt will figure it for you //! #[structopt(default_value, long)] //! prefix: String, // `String` implements both `Default` and `ToString` //! } //! ``` //! //! [`Default`]: https://doc.rust-lang.org/std/default/trait.Default.html //! [`ToString`]: https://doc.rust-lang.org/std/string/trait.ToString.html //! [`Arg::default_value`]: https://docs.rs/clap/2.33.0/clap/struct.Arg.html#method.default_value //! //! //! ## Help messages //! //! In clap, help messages for the whole binary can be specified //! via [`App::about`] and [`App::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. In `structopt`, //! you can use them via [raw methods](#raw-methods), for example: //! //! ``` //! # use structopt::StructOpt; //! //! #[derive(StructOpt)] //! #[structopt(about = "I am a program and I work, just pass `-h`")] //! struct Foo { //! #[structopt(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): //! //! ``` //! # use structopt::StructOpt; //! //! #[derive(StructOpt)] //! /// I am a program and I work, just pass `-h` //! struct Foo { //! /// Pass `-h` and you'll see me! //! bar: String, //! } //! ``` //! //! Doc comments on [top-level](#magical-methods) will be turned into //! `App::about/long_about` call (see below), doc comments on field-level are //! `Arg::help/long_help` calls. //! //! **Important:** //! _________________ //! //! Raw methods have priority over doc comments! //! //! **Top level doc comments always generate `App::about/long_about` calls!** //! If you really want to use the `App::help/long_help` methods (you likely don't), //! use a raw method to override the `App::about` call generated from the doc comment. //! __________________ //! //! ### `long_help` and `--help` //! //! A message passed to [`App::long_about`] or [`Arg::long_help`] will be displayed whenever //! your program is called with `--help` instead of `-h`. Of course, you can //! use them via raw methods as described [above](#help-messages). //! //! The more convenient way is to use a so-called "long" doc comment: //! //! ``` //! # use structopt::StructOpt; //! #[derive(StructOpt)] //! /// 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. //! #[structopt(long)] //! kill_all_humans: bool, //! } //! ``` //! //! A long doc comment consists of three parts: //! * Short summary //! * A blank line (whitespace only) //! * Detailed description, all the rest //! //! In other words, "long" doc comment consists of two or more paragraphs, //! with the first being a summary and the rest being the detailed description. //! //! **A long comment will result in two method calls**, `help()` and //! `long_help()`, so clap will display the summary with `-h` //! and the whole help message on `--help` (see below). //! //! So, the example above will be turned into this (details omitted): //! ``` //! clap::App::new("") //! .about("Hi there, I'm Robo!") //! .long_about("Hi there, I'm Robo!\n\n\ //! 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!") //! // args... //! # ; //! ``` //! //! ### `-h` vs `--help` (A.K.A `help()` vs `long_help()`) //! //! The `-h` flag is not the same as `--help`. //! //! -h corresponds to `Arg::help/App::about` and requests short "summary" messages //! while --help corresponds to `Arg::long_help/App::long_about` and requests more //! detailed, descriptive messages. //! //! It is entirely up to `clap` what happens if you used only one of //! [`Arg::help`]/[`Arg::long_help`], see `clap`'s documentation for these methods. //! //! As of clap v2.33, if only a short message ([`Arg::help`]) or only //! a long ([`Arg::long_help`]) message is provided, clap will use it //! for both -h and --help. The same logic applies to `about/long_about`. //! //! ### Doc comment preprocessing and `#[structopt(verbatim_doc_comment)]` //! //! `structopt` applies some preprocessing to doc comments to ease the most common uses: //! //! * 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. You can ask `structopt` to preserve them //! via `#[structopt(verbatim_doc_comment)]` attribute. //! //! **This attribute must be applied to each field separately**, there's no global switch. //! //! **Important:** //! ______________ //! Keep in mind that `structopt` will *still* remove one leading space from each //! line, even if this attribute is present, to allow for a space between //! `///` and the content. //! //! Also, `structopt` will *still* remove leading and trailing blank lines so //! these formats are equivalent: //! //! ``` //! /** This is a doc comment //! //! Hello! */ //! //! /** //! This is a doc comment //! //! Hello! //! */ //! //! /// This is a doc comment //! /// //! /// Hello! //! # //! # mod m {} //! ``` //! ______________ //! //! [`App::about`]: https://docs.rs/clap/2/clap/struct.App.html#method.about //! [`App::long_about`]: https://docs.rs/clap/2/clap/struct.App.html#method.long_about //! [`Arg::help`]: https://docs.rs/clap/2/clap/struct.Arg.html#method.help //! [`Arg::long_help`]: https://docs.rs/clap/2/clap/struct.Arg.html#method.long_help //! //! ## Environment variable fallback //! //! It is possible to specify an environment variable fallback option for an arguments //! so that its value is taken from the specified environment variable if not //! given through the command-line: //! //! ``` //! # use structopt::StructOpt; //! //! #[derive(StructOpt)] //! struct Foo { //! #[structopt(short, long, env = "PARAMETER_VALUE")] //! parameter_value: String, //! } //! ``` //! //! By default, values from the environment are shown in the help output (i.e. when invoking //! `--help`): //! //! ```shell //! $ cargo run -- --help //! ... //! OPTIONS: //! -p, --parameter-value [env: PARAMETER_VALUE=env_value] //! ``` //! //! In some cases this may be undesirable, for example when being used for passing //! credentials or secret tokens. In those cases you can use `hide_env_values` to avoid //! having structopt emit the actual secret values: //! ``` //! # use structopt::StructOpt; //! //! #[derive(StructOpt)] //! struct Foo { //! #[structopt(long = "secret", env = "SECRET_VALUE", hide_env_values = true)] //! secret_value: String, //! } //! ``` //! //! ### Auto-deriving environment variables //! //! Environment variables tend to be called after the corresponding `struct`'s field, //! as in example above. The field is `secret_value` and the env var is "SECRET_VALUE"; //! the name is the same, except casing is different. //! //! It's pretty tedious and error-prone to type the same name twice, //! so you can ask `structopt` to do that for you. //! //! ``` //! # use structopt::StructOpt; //! //! #[derive(StructOpt)] //! struct Foo { //! #[structopt(long = "secret", env)] //! secret_value: String, //! } //! ``` //! //! It works just like `#[structopt(short/long)]`: if `env` is not set to some concrete //! value the value will be derived from the field's name. This is controlled by //! `#[structopt(rename_all_env)]`. //! //! `rename_all_env` works exactly as `rename_all` (including overriding) //! except default casing is `SCREAMING_SNAKE_CASE` instead of `kebab-case`. //! //! ## Skipping fields //! //! Sometimes you may want to add a field to your `Opt` struct that is not //! a command line option and `clap` should know nothing about it. You can ask //! `structopt` to skip the field entirely via `#[structopt(skip = value)]` //! (`value` must implement `Into`) //! or `#[structopt(skip)]` if you want assign the field with `Default::default()` //! (obviously, the field's type must implement `Default`). //! //! ``` //! # use structopt::StructOpt; //! #[derive(StructOpt)] //! pub struct Opt { //! #[structopt(long, short)] //! number: u32, //! //! // these fields are to be assigned with Default::default() //! //! #[structopt(skip)] //! k: String, //! #[structopt(skip)] //! v: Vec, //! //! // these fields get set explicitly //! //! #[structopt(skip = vec![1, 2, 3])] //! k2: Vec, //! #[structopt(skip = "cake")] // &str implements Into //! v2: String, //! } //! ``` //! //! ## Subcommands //! //! Some applications, especially large ones, split their functionality //! through the use of "subcommands". Each of these act somewhat like a separate //! command, but is part of the larger group. //! One example is `git`, which has subcommands such as `add`, `commit`, //! and `clone`, to mention just a few. //! //! `clap` has this functionality, and `structopt` supports it through enums: //! //! ``` //! # use structopt::StructOpt; //! //! # use std::path::PathBuf; //! #[derive(StructOpt)] //! #[structopt(about = "the stupid content tracker")] //! enum Git { //! Add { //! #[structopt(short)] //! interactive: bool, //! #[structopt(short)] //! patch: bool, //! #[structopt(parse(from_os_str))] //! files: Vec, //! }, //! Fetch { //! #[structopt(long)] //! dry_run: bool, //! #[structopt(long)] //! all: bool, //! repository: Option, //! }, //! Commit { //! #[structopt(short)] //! message: Option, //! #[structopt(short)] //! all: bool, //! }, //! } //! ``` //! //! Using `derive(StructOpt)` on an enum instead of a struct will produce //! a `clap::App` that only takes subcommands. So `git add`, `git fetch`, //! and `git commit` would be commands allowed for the above example. //! //! `structopt` also provides support for applications where certain flags //! need to apply to all subcommands, as well as nested subcommands: //! //! ``` //! # use structopt::StructOpt; //! #[derive(StructOpt)] //! struct MakeCookie { //! #[structopt(name = "supervisor", default_value = "Puck", long = "supervisor")] //! supervising_faerie: String, //! /// The faerie tree this cookie is being made in. //! tree: Option, //! #[structopt(subcommand)] // Note that we mark a field as a subcommand //! cmd: Command, //! } //! //! #[derive(StructOpt)] //! enum Command { //! /// Pound acorns into flour for cookie dough. //! Pound { //! acorns: u32, //! }, //! /// Add magical sparkles -- the secret ingredient! //! Sparkle { //! #[structopt(short, parse(from_occurrences))] //! magicality: u64, //! #[structopt(short)] //! color: String, //! }, //! Finish(Finish), //! } //! //! // Subcommand can also be externalized by using a 1-uple enum variant //! #[derive(StructOpt)] //! struct Finish { //! #[structopt(short)] //! time: u32, //! #[structopt(subcommand)] // Note that we mark a field as a subcommand //! finish_type: FinishType, //! } //! //! // subsubcommand! //! #[derive(StructOpt)] //! enum FinishType { //! Glaze { //! applications: u32, //! }, //! Powder { //! flavor: String, //! dips: u32, //! } //! } //! ``` //! //! Marking a field with `structopt(subcommand)` will add the subcommands of the //! designated enum to the current `clap::App`. The designated enum *must* also //! be derived `StructOpt`. So the above example would take the following //! commands: //! //! + `make-cookie pound 50` //! + `make-cookie sparkle -mmm --color "green"` //! + `make-cookie finish 130 glaze 3` //! //! ### Optional subcommands //! //! Subcommands may be optional: //! //! ``` //! # use structopt::StructOpt; //! #[derive(StructOpt)] //! struct Foo { //! file: String, //! #[structopt(subcommand)] //! cmd: Option, //! } //! //! #[derive(StructOpt)] //! enum Command { //! Bar, //! Baz, //! Quux, //! } //! ``` //! //! ### External subcommands //! //! Sometimes you want to support not only the set of well-known subcommands //! but you also want to allow other, user-driven subcommands. `clap` supports //! this via [`AppSettings::AllowExternalSubcommands`]. //! //! `structopt` provides it's own dedicated syntax for that: //! //! ``` //! # use structopt::StructOpt; //! #[derive(Debug, PartialEq, StructOpt)] //! struct Opt { //! #[structopt(subcommand)] //! sub: Subcommands, //! } //! //! #[derive(Debug, PartialEq, StructOpt)] //! enum Subcommands { //! // normal subcommand //! Add, //! //! // `external_subcommand` tells structopt to put //! // all the extra arguments into this Vec //! #[structopt(external_subcommand)] //! Other(Vec), //! } //! //! // normal subcommand //! assert_eq!( //! Opt::from_iter(&["test", "add"]), //! Opt { //! sub: Subcommands::Add //! } //! ); //! //! assert_eq!( //! Opt::from_iter(&["test", "git", "status"]), //! Opt { //! sub: Subcommands::Other(vec!["git".into(), "status".into()]) //! } //! ); //! //! // Please note that if you'd wanted to allow "no subcommands at all" case //! // you should have used `sub: Option` above //! assert!(Opt::from_iter_safe(&["test"]).is_err()); //! ``` //! //! In other words, you just add an extra tuple variant marked with //! `#[structopt(subcommand)]`, and its type must be either //! `Vec` or `Vec`. `structopt` will detect `String` in this context //! and use appropriate `clap` API. //! //! [`AppSettings::AllowExternalSubcommands`]: https://docs.rs/clap/2.32.0/clap/enum.AppSettings.html#variant.AllowExternalSubcommands //! //! ### Flattening subcommands //! //! It is also possible to combine multiple enums of subcommands into one. //! All the subcommands will be on the same level. //! //! ``` //! # use structopt::StructOpt; //! #[derive(StructOpt)] //! enum BaseCli { //! Ghost10 { //! arg1: i32, //! } //! } //! //! #[derive(StructOpt)] //! enum Opt { //! #[structopt(flatten)] //! BaseCli(BaseCli), //! Dex { //! arg2: i32, //! }, //! } //! ``` //! //! ```shell //! cli ghost10 42 //! cli dex 42 //! ``` //! //! ## Flattening //! //! It can sometimes be useful to group related arguments in a substruct, //! while keeping the command-line interface flat. In these cases you can mark //! a field as `flatten` and give it another type that derives `StructOpt`: //! //! ``` //! # use structopt::StructOpt; //! #[derive(StructOpt)] //! struct Cmdline { //! /// switch on verbosity //! #[structopt(short)] //! verbose: bool, //! #[structopt(flatten)] //! daemon_opts: DaemonOpts, //! } //! //! #[derive(StructOpt)] //! struct DaemonOpts { //! /// daemon user //! #[structopt(short)] //! user: String, //! /// daemon group //! #[structopt(short)] //! group: String, //! } //! ``` //! //! In this example, the derived `Cmdline` parser will support the options `-v`, //! `-u` and `-g`. //! //! This feature also makes it possible to define a `StructOpt` struct in a //! library, parse the corresponding arguments in the main argument parser, and //! pass off this struct to a handler provided by that library. //! //! ## Custom string parsers //! //! If the field type does not have a `FromStr` implementation, or you would //! like to provide a custom parsing scheme other than `FromStr`, you may //! provide a custom string parser using `parse(...)` like this: //! //! ``` //! # use structopt::StructOpt; //! use std::num::ParseIntError; //! use std::path::PathBuf; //! //! fn parse_hex(src: &str) -> Result { //! u32::from_str_radix(src, 16) //! } //! //! #[derive(StructOpt)] //! struct HexReader { //! #[structopt(short, parse(try_from_str = parse_hex))] //! number: u32, //! #[structopt(short, parse(from_os_str))] //! output: PathBuf, //! } //! ``` //! //! There are five kinds of custom parsers: //! //! | Kind | Signature | Default | //! |-------------------|---------------------------------------|---------------------------------| //! | `from_str` | `fn(&str) -> T` | `::std::convert::From::from` | //! | `try_from_str` | `fn(&str) -> Result` | `::std::str::FromStr::from_str` | //! | `from_os_str` | `fn(&OsStr) -> T` | `::std::convert::From::from` | //! | `try_from_os_str` | `fn(&OsStr) -> Result` | (no default function) | //! | `from_occurrences`| `fn(u64) -> T` | `value as T` | //! | `from_flag` | `fn(bool) -> T` | `::std::convert::From::from` | //! //! The `from_occurrences` parser is special. Using `parse(from_occurrences)` //! results in the _number of flags occurrences_ being stored in the relevant //! field or being passed to the supplied function. In other words, it converts //! something like `-vvv` to `3`. This is equivalent to //! `.takes_value(false).multiple(true)`. Note that the default parser can only //! be used with fields of integer types (`u8`, `usize`, `i64`, etc.). //! //! The `from_flag` parser is also special. Using `parse(from_flag)` or //! `parse(from_flag = some_func)` will result in the field being treated as a //! flag even if it does not have type `bool`. //! //! When supplying a custom string parser, `bool` will not be treated specially: //! //! Type | Effect | Added method call to `clap::Arg` //! ------------|-------------------|-------------------------------------- //! `Option` | optional argument | `.takes_value(true).multiple(false)` //! `Vec` | list of arguments | `.takes_value(true).multiple(true)` //! `T` | required argument | `.takes_value(true).multiple(false).required(!has_default)` //! //! In the `try_from_*` variants, the function will run twice on valid input: //! once to validate, and once to parse. Hence, make sure the function is //! side-effect-free. //! //! ## Generics //! //! Generic structs and enums can be used. They require explicit trait bounds //! on any generic types that will be used by the `StructOpt` derive macro. In //! some cases, associated types will require additional bounds. See the usage //! of `FromStr` below for an example of this. //! //! ``` //! # use structopt::StructOpt; //! use std::{fmt, str::FromStr}; //! //! // a struct with single custom argument //! #[derive(StructOpt)] //! struct GenericArgs where ::Err: fmt::Display + fmt::Debug { //! generic_arg_1: String, //! generic_arg_2: String, //! custom_arg_1: T, //! } //! ``` //! //! or //! //! ``` //! # use structopt::StructOpt; //! // a struct with multiple custom arguments in a substructure //! #[derive(StructOpt)] //! struct GenericArgs { //! generic_arg_1: String, //! generic_arg_2: String, //! #[structopt(flatten)] //! custom_args: T, //! } //! ``` // those mains are for a reason #![allow(clippy::needless_doctest_main)] #[doc(hidden)] pub use structopt_derive::*; use std::ffi::OsString; /// Re-exports pub use clap; #[cfg(feature = "paw")] pub use paw_dep as paw; /// **This is NOT PUBLIC API**. #[doc(hidden)] pub use lazy_static; /// A struct that is converted from command line arguments. pub trait StructOpt { /// Returns [`clap::App`] corresponding to the struct. fn clap<'a, 'b>() -> clap::App<'a, 'b>; /// Builds the struct from [`clap::ArgMatches`]. It's guaranteed to succeed /// if `matches` originates from an `App` generated by [`StructOpt::clap`] called on /// the same type, otherwise it must panic. fn from_clap(matches: &clap::ArgMatches<'_>) -> Self; /// Builds the struct from the command line arguments ([`std::env::args_os`]). /// Calls [`clap::Error::exit`] on failure, printing the error message and aborting the program. fn from_args() -> Self where Self: Sized, { Self::from_clap(&Self::clap().get_matches()) } /// Builds the struct from the command line arguments ([`std::env::args_os`]). /// Unlike [`StructOpt::from_args`], returns [`clap::Error`] on failure instead of aborting the program, /// so calling [`.exit`][clap::Error::exit] is up to you. fn from_args_safe() -> Result where Self: Sized, { Self::clap() .get_matches_safe() .map(|matches| Self::from_clap(&matches)) } /// Gets the struct from any iterator such as a `Vec` of your making. /// Print the error message and quit the program in case of failure. /// /// **NOTE**: The first argument will be parsed as the binary name unless /// [`clap::AppSettings::NoBinaryName`] has been used. fn from_iter(iter: I) -> Self where Self: Sized, I: IntoIterator, I::Item: Into + Clone, { Self::from_clap(&Self::clap().get_matches_from(iter)) } /// Gets the struct from any iterator such as a `Vec` of your making. /// /// Returns a [`clap::Error`] in case of failure. This does *not* exit in the /// case of `--help` or `--version`, to achieve the same behavior as /// [`from_iter()`][StructOpt::from_iter] you must call [`.exit()`][clap::Error::exit] on the error value. /// /// **NOTE**: The first argument will be parsed as the binary name unless /// [`clap::AppSettings::NoBinaryName`] has been used. fn from_iter_safe(iter: I) -> Result where Self: Sized, I: IntoIterator, I::Item: Into + Clone, { Ok(Self::from_clap(&Self::clap().get_matches_from_safe(iter)?)) } } /// This trait is NOT API. **SUBJECT TO CHANGE WITHOUT NOTICE!**. #[doc(hidden)] pub trait StructOptInternal: StructOpt { fn augment_clap<'a, 'b>(app: clap::App<'a, 'b>) -> clap::App<'a, 'b> { app } fn is_subcommand() -> bool { false } fn from_subcommand<'a, 'b>(_sub: (&'b str, Option<&'b clap::ArgMatches<'a>>)) -> Option where Self: std::marker::Sized, { None } } impl StructOpt for Box { fn clap<'a, 'b>() -> clap::App<'a, 'b> { ::clap() } fn from_clap(matches: &clap::ArgMatches<'_>) -> Self { Box::new(::from_clap(matches)) } } impl StructOptInternal for Box { #[doc(hidden)] fn is_subcommand() -> bool { ::is_subcommand() } #[doc(hidden)] fn from_subcommand<'a, 'b>(sub: (&'b str, Option<&'b clap::ArgMatches<'a>>)) -> Option { ::from_subcommand(sub).map(Box::new) } #[doc(hidden)] fn augment_clap<'a, 'b>(app: clap::App<'a, 'b>) -> clap::App<'a, 'b> { ::augment_clap(app) } } structopt-0.3.26/tests/argument_naming.rs000064400000000000000000000200420072674642500166740ustar 00000000000000use structopt::StructOpt; #[test] fn test_single_word_enum_variant_is_default_renamed_into_kebab_case() { #[derive(StructOpt, Debug, PartialEq)] enum Opt { Command { foo: u32 }, } assert_eq!( Opt::Command { foo: 0 }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "command", "0"])) ); } #[test] fn test_multi_word_enum_variant_is_renamed() { #[derive(StructOpt, Debug, PartialEq)] enum Opt { FirstCommand { foo: u32 }, } assert_eq!( Opt::FirstCommand { foo: 0 }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "first-command", "0"])) ); } #[test] fn test_standalone_long_generates_kebab_case() { #[derive(StructOpt, Debug, PartialEq)] #[allow(non_snake_case)] struct Opt { #[structopt(long)] FOO_OPTION: bool, } assert_eq!( Opt { FOO_OPTION: true }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--foo-option"])) ); } #[test] fn test_custom_long_overwrites_default_name() { #[derive(StructOpt, Debug, PartialEq)] struct Opt { #[structopt(long = "foo")] foo_option: bool, } assert_eq!( Opt { foo_option: true }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--foo"])) ); } #[test] fn test_standalone_long_uses_previous_defined_custom_name() { #[derive(StructOpt, Debug, PartialEq)] struct Opt { #[structopt(name = "foo", long)] foo_option: bool, } assert_eq!( Opt { foo_option: true }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--foo"])) ); } #[test] fn test_standalone_long_ignores_afterwards_defined_custom_name() { #[derive(StructOpt, Debug, PartialEq)] struct Opt { #[structopt(long, name = "foo")] foo_option: bool, } assert_eq!( Opt { foo_option: true }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--foo-option"])) ); } #[test] fn test_standalone_short_generates_kebab_case() { #[derive(StructOpt, Debug, PartialEq)] #[allow(non_snake_case)] struct Opt { #[structopt(short)] FOO_OPTION: bool, } assert_eq!( Opt { FOO_OPTION: true }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-f"])) ); } #[test] fn test_custom_short_overwrites_default_name() { #[derive(StructOpt, Debug, PartialEq)] struct Opt { #[structopt(short = "o")] foo_option: bool, } assert_eq!( Opt { foo_option: true }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-o"])) ); } #[test] fn test_standalone_short_uses_previous_defined_custom_name() { #[derive(StructOpt, Debug, PartialEq)] struct Opt { #[structopt(name = "option", short)] foo_option: bool, } assert_eq!( Opt { foo_option: true }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-o"])) ); } #[test] fn test_standalone_short_ignores_afterwards_defined_custom_name() { #[derive(StructOpt, Debug, PartialEq)] struct Opt { #[structopt(short, name = "option")] foo_option: bool, } assert_eq!( Opt { foo_option: true }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-f"])) ); } #[test] fn test_standalone_long_uses_previous_defined_casing() { #[derive(StructOpt, Debug, PartialEq)] struct Opt { #[structopt(rename_all = "screaming_snake", long)] foo_option: bool, } assert_eq!( Opt { foo_option: true }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--FOO_OPTION"])) ); } #[test] fn test_standalone_short_uses_previous_defined_casing() { #[derive(StructOpt, Debug, PartialEq)] struct Opt { #[structopt(rename_all = "screaming_snake", short)] foo_option: bool, } assert_eq!( Opt { foo_option: true }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-F"])) ); } #[test] fn test_standalone_long_works_with_verbatim_casing() { #[derive(StructOpt, Debug, PartialEq)] #[allow(non_snake_case)] struct Opt { #[structopt(rename_all = "verbatim", long)] _fOO_oPtiON: bool, } assert_eq!( Opt { _fOO_oPtiON: true }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--_fOO_oPtiON"])) ); } #[test] fn test_standalone_short_works_with_verbatim_casing() { #[derive(StructOpt, Debug, PartialEq)] struct Opt { #[structopt(rename_all = "verbatim", short)] _foo: bool, } assert_eq!( Opt { _foo: true }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-_"])) ); } #[test] fn test_rename_all_is_propagated_from_struct_to_fields() { #[derive(StructOpt, Debug, PartialEq)] #[structopt(rename_all = "screaming_snake")] struct Opt { #[structopt(long)] foo: bool, } assert_eq!( Opt { foo: true }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--FOO"])) ); } #[test] fn test_rename_all_is_not_propagated_from_struct_into_flattened() { #[derive(StructOpt, Debug, PartialEq)] #[structopt(rename_all = "screaming_snake")] struct Opt { #[structopt(flatten)] foo: Foo, } #[derive(StructOpt, Debug, PartialEq)] struct Foo { #[structopt(long)] foo: bool, } assert_eq!( Opt { foo: Foo { foo: true } }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--foo"])) ); } #[test] fn test_rename_all_is_not_propagated_from_struct_into_subcommand() { #[derive(StructOpt, Debug, PartialEq)] #[structopt(rename_all = "screaming_snake")] struct Opt { #[structopt(subcommand)] foo: Foo, } #[derive(StructOpt, Debug, PartialEq)] enum Foo { Command { #[structopt(long)] foo: bool, }, } assert_eq!( Opt { foo: Foo::Command { foo: true } }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "command", "--foo"])) ); } #[test] fn test_rename_all_is_propagated_from_enum_to_variants_and_their_fields() { #[derive(StructOpt, Debug, PartialEq)] #[structopt(rename_all = "screaming_snake")] enum Opt { FirstVariant, SecondVariant { #[structopt(long)] foo: bool, }, } assert_eq!( Opt::FirstVariant, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "FIRST_VARIANT"])) ); assert_eq!( Opt::SecondVariant { foo: true }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "SECOND_VARIANT", "--FOO"])) ); } #[test] fn test_rename_all_is_propagation_can_be_overridden() { #[derive(StructOpt, Debug, PartialEq)] #[structopt(rename_all = "screaming_snake")] enum Opt { #[structopt(rename_all = "kebab_case")] FirstVariant { #[structopt(long)] foo_option: bool, }, SecondVariant { #[structopt(rename_all = "kebab_case", long)] foo_option: bool, }, } assert_eq!( Opt::FirstVariant { foo_option: true }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "first-variant", "--foo-option"])) ); assert_eq!( Opt::SecondVariant { foo_option: true }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "SECOND_VARIANT", "--foo-option"])) ); } #[test] fn test_lower_is_renamed() { #[derive(StructOpt, Debug, PartialEq)] struct Opt { #[structopt(rename_all = "lower", long)] foo_option: bool, } assert_eq!( Opt { foo_option: true }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--foooption"])) ); } #[test] fn test_upper_is_renamed() { #[derive(StructOpt, Debug, PartialEq)] struct Opt { #[structopt(rename_all = "upper", long)] foo_option: bool, } assert_eq!( Opt { foo_option: true }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--FOOOPTION"])) ); } structopt-0.3.26/tests/arguments.rs000064400000000000000000000046040072674642500155340ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::clap; use structopt::StructOpt; #[test] fn required_argument() { #[derive(StructOpt, PartialEq, Debug)] struct Opt { arg: i32, } assert_eq!(Opt { arg: 42 }, Opt::from_iter(&["test", "42"])); assert!(Opt::clap().get_matches_from_safe(&["test"]).is_err()); assert!(Opt::clap() .get_matches_from_safe(&["test", "42", "24"]) .is_err()); } #[test] fn optional_argument() { #[derive(StructOpt, PartialEq, Debug)] struct Opt { arg: Option, } assert_eq!(Opt { arg: Some(42) }, Opt::from_iter(&["test", "42"])); assert_eq!(Opt { arg: None }, Opt::from_iter(&["test"])); assert!(Opt::clap() .get_matches_from_safe(&["test", "42", "24"]) .is_err()); } #[test] fn argument_with_default() { #[derive(StructOpt, PartialEq, Debug)] struct Opt { #[structopt(default_value = "42")] arg: i32, } assert_eq!(Opt { arg: 24 }, Opt::from_iter(&["test", "24"])); assert_eq!(Opt { arg: 42 }, Opt::from_iter(&["test"])); assert!(Opt::clap() .get_matches_from_safe(&["test", "42", "24"]) .is_err()); } #[test] fn arguments() { #[derive(StructOpt, PartialEq, Debug)] struct Opt { arg: Vec, } assert_eq!(Opt { arg: vec![24] }, Opt::from_iter(&["test", "24"])); assert_eq!(Opt { arg: vec![] }, Opt::from_iter(&["test"])); assert_eq!( Opt { arg: vec![24, 42] }, Opt::from_iter(&["test", "24", "42"]) ); } #[test] fn arguments_safe() { #[derive(StructOpt, PartialEq, Debug)] struct Opt { arg: Vec, } assert_eq!( Opt { arg: vec![24] }, Opt::from_iter_safe(&["test", "24"]).unwrap() ); assert_eq!(Opt { arg: vec![] }, Opt::from_iter_safe(&["test"]).unwrap()); assert_eq!( Opt { arg: vec![24, 42] }, Opt::from_iter_safe(&["test", "24", "42"]).unwrap() ); assert_eq!( clap::ErrorKind::ValueValidation, Opt::from_iter_safe(&["test", "NOPE"]).err().unwrap().kind ); } structopt-0.3.26/tests/author_version_about.rs000064400000000000000000000030410072674642500177620ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. mod utils; use structopt::StructOpt; use utils::*; #[test] fn no_author_version_about() { #[derive(StructOpt, PartialEq, Debug)] #[structopt(name = "foo", no_version)] struct Opt {} let output = get_long_help::(); assert!(output.starts_with("foo \n\nUSAGE:")); } #[test] fn use_env() { #[derive(StructOpt, PartialEq, Debug)] #[structopt(author, about)] struct Opt {} let output = get_long_help::(); assert!(output.starts_with("structopt 0.")); assert!(output.contains("Guillaume Pinot , others")); assert!(output.contains("Parse command line argument by defining a struct.")); } #[test] fn explicit_version_not_str() { const VERSION: &str = "custom version"; #[derive(StructOpt)] #[structopt(version = VERSION)] pub struct Opt {} let output = get_long_help::(); assert!(output.contains("custom version")); } #[test] fn no_version_gets_propagated() { #[derive(StructOpt, PartialEq, Debug)] #[structopt(no_version)] enum Action { Move, } let output = get_subcommand_long_help::("move"); assert_eq!(output.lines().next(), Some("test-move ")); } structopt-0.3.26/tests/custom-string-parsers.rs000064400000000000000000000176250072674642500200310ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; use std::ffi::{CString, OsStr, OsString}; use std::num::ParseIntError; use std::path::PathBuf; #[derive(StructOpt, PartialEq, Debug)] struct PathOpt { #[structopt(short, long, parse(from_os_str))] path: PathBuf, #[structopt(short, default_value = "../", parse(from_os_str))] default_path: PathBuf, #[structopt(short, parse(from_os_str))] vector_path: Vec, #[structopt(short, parse(from_os_str))] option_path_1: Option, #[structopt(short = "q", parse(from_os_str))] option_path_2: Option, } #[test] fn test_path_opt_simple() { assert_eq!( PathOpt { path: PathBuf::from("/usr/bin"), default_path: PathBuf::from("../"), vector_path: vec![ PathBuf::from("/a/b/c"), PathBuf::from("/d/e/f"), PathBuf::from("/g/h/i"), ], option_path_1: None, option_path_2: Some(PathBuf::from("j.zip")), }, PathOpt::from_clap(&PathOpt::clap().get_matches_from(&[ "test", "-p", "/usr/bin", "-v", "/a/b/c", "-v", "/d/e/f", "-v", "/g/h/i", "-q", "j.zip", ])) ); } fn parse_hex(input: &str) -> Result { u64::from_str_radix(input, 16) } #[derive(StructOpt, PartialEq, Debug)] struct HexOpt { #[structopt(short, parse(try_from_str = parse_hex))] number: u64, } #[test] #[allow(clippy::unreadable_literal)] fn test_parse_hex() { assert_eq!( HexOpt { number: 5 }, HexOpt::from_clap(&HexOpt::clap().get_matches_from(&["test", "-n", "5"])) ); assert_eq!( HexOpt { number: 0xabcdef }, HexOpt::from_clap(&HexOpt::clap().get_matches_from(&["test", "-n", "abcdef"])) ); let err = HexOpt::clap() .get_matches_from_safe(&["test", "-n", "gg"]) .unwrap_err(); assert!( err.message.contains("invalid digit found in string"), "{}", err ); } fn custom_parser_1(_: &str) -> &'static str { "A" } fn custom_parser_2(_: &str) -> Result<&'static str, u32> { Ok("B") } fn custom_parser_3(_: &OsStr) -> &'static str { "C" } fn custom_parser_4(_: &OsStr) -> Result<&'static str, OsString> { Ok("D") } #[derive(StructOpt, PartialEq, Debug)] struct NoOpOpt { #[structopt(short, parse(from_str = custom_parser_1))] a: &'static str, #[structopt(short, parse(try_from_str = custom_parser_2))] b: &'static str, #[structopt(short, parse(from_os_str = custom_parser_3))] c: &'static str, #[structopt(short, parse(try_from_os_str = custom_parser_4))] d: &'static str, } #[test] fn test_every_custom_parser() { assert_eq!( NoOpOpt { a: "A", b: "B", c: "C", d: "D" }, NoOpOpt::from_clap( &NoOpOpt::clap().get_matches_from(&["test", "-a=?", "-b=?", "-c=?", "-d=?"]) ) ); } // Note: can't use `Vec` directly, as structopt would instead look for // conversion function from `&str` to `u8`. type Bytes = Vec; #[derive(StructOpt, PartialEq, Debug)] struct DefaultedOpt { #[structopt(short, parse(from_str))] bytes: Bytes, #[structopt(short, parse(try_from_str))] integer: u64, #[structopt(short, parse(from_os_str))] path: PathBuf, } #[test] fn test_parser_with_default_value() { assert_eq!( DefaultedOpt { bytes: b"E\xc2\xb2=p\xc2\xb2c\xc2\xb2+m\xc2\xb2c\xe2\x81\xb4".to_vec(), integer: 9000, path: PathBuf::from("src/lib.rs"), }, DefaultedOpt::from_clap(&DefaultedOpt::clap().get_matches_from(&[ "test", "-b", "E²=p²c²+m²c⁴", "-i", "9000", "-p", "src/lib.rs", ])) ); } #[derive(PartialEq, Debug)] struct Foo(u8); fn foo(value: u64) -> Foo { Foo(value as u8) } #[derive(StructOpt, PartialEq, Debug)] struct Occurrences { #[structopt(short, long, parse(from_occurrences))] signed: i32, #[structopt(short, parse(from_occurrences))] little_signed: i8, #[structopt(short, parse(from_occurrences))] unsigned: usize, #[structopt(short = "r", parse(from_occurrences))] little_unsigned: u8, #[structopt(short, long, parse(from_occurrences = foo))] custom: Foo, } #[test] fn test_parser_occurrences() { assert_eq!( Occurrences { signed: 3, little_signed: 1, unsigned: 0, little_unsigned: 4, custom: Foo(5), }, Occurrences::from_clap(&Occurrences::clap().get_matches_from(&[ "test", "-s", "--signed", "--signed", "-l", "-rrrr", "-cccc", "--custom", ])) ); } #[test] fn test_custom_bool() { fn parse_bool(s: &str) -> Result { match s { "true" => Ok(true), "false" => Ok(false), _ => Err(format!("invalid bool {}", s)), } } #[derive(StructOpt, PartialEq, Debug)] struct Opt { #[structopt(short, parse(try_from_str = parse_bool))] debug: bool, #[structopt( short, default_value = "false", parse(try_from_str = parse_bool) )] verbose: bool, #[structopt(short, parse(try_from_str = parse_bool))] tribool: Option, #[structopt(short, parse(try_from_str = parse_bool))] bitset: Vec, } assert!(Opt::clap().get_matches_from_safe(&["test"]).is_err()); assert!(Opt::clap().get_matches_from_safe(&["test", "-d"]).is_err()); assert!(Opt::clap() .get_matches_from_safe(&["test", "-dfoo"]) .is_err()); assert_eq!( Opt { debug: false, verbose: false, tribool: None, bitset: vec![], }, Opt::from_iter(&["test", "-dfalse"]) ); assert_eq!( Opt { debug: true, verbose: false, tribool: None, bitset: vec![], }, Opt::from_iter(&["test", "-dtrue"]) ); assert_eq!( Opt { debug: true, verbose: false, tribool: None, bitset: vec![], }, Opt::from_iter(&["test", "-dtrue", "-vfalse"]) ); assert_eq!( Opt { debug: true, verbose: true, tribool: None, bitset: vec![], }, Opt::from_iter(&["test", "-dtrue", "-vtrue"]) ); assert_eq!( Opt { debug: true, verbose: false, tribool: Some(false), bitset: vec![], }, Opt::from_iter(&["test", "-dtrue", "-tfalse"]) ); assert_eq!( Opt { debug: true, verbose: false, tribool: Some(true), bitset: vec![], }, Opt::from_iter(&["test", "-dtrue", "-ttrue"]) ); assert_eq!( Opt { debug: true, verbose: false, tribool: None, bitset: vec![false, true, false, false], }, Opt::from_iter(&["test", "-dtrue", "-bfalse", "-btrue", "-bfalse", "-bfalse"]) ); } #[test] fn test_cstring() { #[derive(StructOpt)] struct Opt { #[structopt(parse(try_from_str = CString::new))] c_string: CString, } assert!(Opt::clap().get_matches_from_safe(&["test"]).is_err()); assert_eq!(Opt::from_iter(&["test", "bla"]).c_string.to_bytes(), b"bla"); assert!(Opt::clap() .get_matches_from_safe(&["test", "bla\0bla"]) .is_err()); } structopt-0.3.26/tests/default_value.rs000064400000000000000000000006410072674642500163440ustar 00000000000000use structopt::StructOpt; mod utils; use utils::*; #[test] fn auto_default_value() { #[derive(StructOpt, PartialEq, Debug)] struct Opt { #[structopt(default_value)] arg: i32, } assert_eq!(Opt { arg: 0 }, Opt::from_iter(&["test"])); assert_eq!(Opt { arg: 1 }, Opt::from_iter(&["test", "1"])); let help = get_long_help::(); assert!(help.contains("[default: 0]")); } structopt-0.3.26/tests/deny-warnings.rs000064400000000000000000000021630072674642500163120ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. #![deny(warnings)] use structopt::StructOpt; fn try_str(s: &str) -> Result { Ok(s.into()) } #[test] fn warning_never_struct() { #[derive(Debug, PartialEq, StructOpt)] struct Opt { #[structopt(parse(try_from_str = try_str))] s: String, } assert_eq!( Opt { s: "foo".to_string() }, Opt::from_iter(&["test", "foo"]) ); } #[test] fn warning_never_enum() { #[derive(Debug, PartialEq, StructOpt)] enum Opt { Foo { #[structopt(parse(try_from_str = try_str))] s: String, }, } assert_eq!( Opt::Foo { s: "foo".to_string() }, Opt::from_iter(&["test", "foo", "foo"]) ); } structopt-0.3.26/tests/doc-comments-help.rs000064400000000000000000000115500072674642500170430ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. mod utils; use structopt::StructOpt; use utils::*; #[test] fn doc_comments() { /// Lorem ipsum #[derive(StructOpt, PartialEq, Debug)] struct LoremIpsum { /// Fooify a bar /// and a baz #[structopt(short, long)] foo: bool, } let help = get_long_help::(); assert!(help.contains("Lorem ipsum")); assert!(help.contains("Fooify a bar and a baz")); } #[test] fn help_is_better_than_comments() { /// Lorem ipsum #[derive(StructOpt, PartialEq, Debug)] #[structopt(name = "lorem-ipsum", about = "Dolor sit amet")] struct LoremIpsum { /// Fooify a bar #[structopt(short, long, help = "DO NOT PASS A BAR UNDER ANY CIRCUMSTANCES")] foo: bool, } let help = get_long_help::(); assert!(help.contains("Dolor sit amet")); assert!(!help.contains("Lorem ipsum")); assert!(help.contains("DO NOT PASS A BAR")); } #[test] fn empty_line_in_doc_comment_is_double_linefeed() { /// Foo. /// /// Bar #[derive(StructOpt, PartialEq, Debug)] #[structopt(name = "lorem-ipsum", no_version)] struct LoremIpsum {} let help = get_long_help::(); assert!(help.starts_with("lorem-ipsum \nFoo.\n\nBar\n\nUSAGE:")); } #[test] fn field_long_doc_comment_both_help_long_help() { /// Lorem ipsumclap #[derive(StructOpt, PartialEq, Debug)] #[structopt(name = "lorem-ipsum", about = "Dolor sit amet")] struct LoremIpsum { /// Dot is removed from multiline comments. /// /// Long help #[structopt(long)] foo: bool, /// Dot is removed from one short comment. #[structopt(long)] bar: bool, } let short_help = get_help::(); let long_help = get_long_help::(); assert!(short_help.contains("Dot is removed from one short comment")); assert!(!short_help.contains("Dot is removed from one short comment.")); assert!(short_help.contains("Dot is removed from multiline comments")); assert!(!short_help.contains("Dot is removed from multiline comments.")); assert!(long_help.contains("Long help")); assert!(!short_help.contains("Long help")); } #[test] fn top_long_doc_comment_both_help_long_help() { /// Lorem ipsumclap #[derive(StructOpt, Debug)] #[structopt(name = "lorem-ipsum", about = "Dolor sit amet")] struct LoremIpsum { #[structopt(subcommand)] foo: SubCommand, } #[derive(StructOpt, Debug)] pub enum SubCommand { /// DO NOT PASS A BAR UNDER ANY CIRCUMSTANCES /// /// Or something else Foo { #[structopt(help = "foo")] bars: Vec, }, } let short_help = get_help::(); let long_help = get_subcommand_long_help::("foo"); assert!(!short_help.contains("Or something else")); assert!(long_help.contains("DO NOT PASS A BAR UNDER ANY CIRCUMSTANCES")); assert!(long_help.contains("Or something else")); } #[test] fn verbatim_doc_comment() { /// DANCE! /// /// () /// | /// ( () ) /// ) ________ // ) /// () |\ \ // /// ( \\__ \ ______\// /// \__) | | /// | | | /// \ | | /// \|_______| /// // \\ /// (( || /// \\ || /// ( () || /// ( () ) ) #[derive(StructOpt, Debug)] #[structopt(verbatim_doc_comment)] struct SeeFigure1 { #[structopt(long)] foo: bool, } let help = get_long_help::(); let sample = r#" () | ( () ) ) ________ // ) () |\ \ // ( \\__ \ ______\// \__) | | | | | \ | | \|_______| // \\ (( || \\ || ( () || ( () ) )"#; assert!(help.contains(sample)) } #[test] fn verbatim_doc_comment_field() { #[derive(StructOpt, Debug)] struct App { /// This help ends in a period. #[structopt(long, verbatim_doc_comment)] foo: bool, /// This help does not end in a period. #[structopt(long)] bar: bool, } let help = get_long_help::(); let sample = r#" --bar This help does not end in a period --foo This help ends in a period."#; assert!(help.contains(sample)) } structopt-0.3.26/tests/explicit_name_no_renaming.rs000064400000000000000000000012340072674642500207200ustar 00000000000000mod utils; use structopt::StructOpt; use utils::*; #[test] fn explicit_short_long_no_rename() { #[derive(StructOpt, PartialEq, Debug)] struct Opt { #[structopt(short = ".", long = ".foo")] foo: Vec, } assert_eq!( Opt { foo: vec!["short".into(), "long".into()] }, Opt::from_iter(&["test", "-.", "short", "--.foo", "long"]) ); } #[test] fn explicit_name_no_rename() { #[derive(StructOpt, PartialEq, Debug)] struct Opt { #[structopt(name = ".options")] foo: Vec, } let help = get_long_help::(); assert!(help.contains("[.options]...")) } structopt-0.3.26/tests/flags.rs000064400000000000000000000114370072674642500146250ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[test] fn unique_flag() { #[derive(StructOpt, PartialEq, Debug)] struct Opt { #[structopt(short, long)] alice: bool, } assert_eq!( Opt { alice: false }, Opt::from_clap(&Opt::clap().get_matches_from(&["test"])) ); assert_eq!( Opt { alice: true }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a"])) ); assert_eq!( Opt { alice: true }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--alice"])) ); assert!(Opt::clap().get_matches_from_safe(&["test", "-i"]).is_err()); assert!(Opt::clap() .get_matches_from_safe(&["test", "-a", "foo"]) .is_err()); assert!(Opt::clap() .get_matches_from_safe(&["test", "-a", "-a"]) .is_err()); assert!(Opt::clap() .get_matches_from_safe(&["test", "-a", "--alice"]) .is_err()); } #[test] fn multiple_flag() { #[derive(StructOpt, PartialEq, Debug)] struct Opt { #[structopt(short, long, parse(from_occurrences))] alice: u64, #[structopt(short, long, parse(from_occurrences))] bob: u8, } assert_eq!( Opt { alice: 0, bob: 0 }, Opt::from_clap(&Opt::clap().get_matches_from(&["test"])) ); assert_eq!( Opt { alice: 1, bob: 0 }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a"])) ); assert_eq!( Opt { alice: 2, bob: 0 }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "-a"])) ); assert_eq!( Opt { alice: 2, bob: 2 }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "--alice", "-bb"])) ); assert_eq!( Opt { alice: 3, bob: 1 }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-aaa", "--bob"])) ); assert!(Opt::clap().get_matches_from_safe(&["test", "-i"]).is_err()); assert!(Opt::clap() .get_matches_from_safe(&["test", "-a", "foo"]) .is_err()); } fn parse_from_flag(b: bool) -> std::sync::atomic::AtomicBool { std::sync::atomic::AtomicBool::new(b) } #[test] fn non_bool_flags() { #[derive(StructOpt, Debug)] struct Opt { #[structopt(short, long, parse(from_flag = parse_from_flag))] alice: std::sync::atomic::AtomicBool, #[structopt(short, long, parse(from_flag))] bob: std::sync::atomic::AtomicBool, } let falsey = Opt::from_clap(&Opt::clap().get_matches_from(&["test"])); assert!(!falsey.alice.load(std::sync::atomic::Ordering::Relaxed)); assert!(!falsey.bob.load(std::sync::atomic::Ordering::Relaxed)); let alice = Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a"])); assert!(alice.alice.load(std::sync::atomic::Ordering::Relaxed)); assert!(!alice.bob.load(std::sync::atomic::Ordering::Relaxed)); let bob = Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-b"])); assert!(!bob.alice.load(std::sync::atomic::Ordering::Relaxed)); assert!(bob.bob.load(std::sync::atomic::Ordering::Relaxed)); let both = Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-b", "-a"])); assert!(both.alice.load(std::sync::atomic::Ordering::Relaxed)); assert!(both.bob.load(std::sync::atomic::Ordering::Relaxed)); } #[test] fn combined_flags() { #[derive(StructOpt, PartialEq, Debug)] struct Opt { #[structopt(short, long)] alice: bool, #[structopt(short, long, parse(from_occurrences))] bob: u64, } assert_eq!( Opt { alice: false, bob: 0 }, Opt::from_clap(&Opt::clap().get_matches_from(&["test"])) ); assert_eq!( Opt { alice: true, bob: 0 }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a"])) ); assert_eq!( Opt { alice: true, bob: 0 }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a"])) ); assert_eq!( Opt { alice: false, bob: 1 }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-b"])) ); assert_eq!( Opt { alice: true, bob: 1 }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--alice", "--bob"])) ); assert_eq!( Opt { alice: true, bob: 4 }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-bb", "-a", "-bb"])) ); } structopt-0.3.26/tests/flatten.rs000064400000000000000000000101730072674642500151620ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; mod utils; #[test] fn flatten() { #[derive(StructOpt, PartialEq, Debug)] struct Common { arg: i32, } #[derive(StructOpt, PartialEq, Debug)] struct Opt { #[structopt(flatten)] common: Common, } assert_eq!( Opt { common: Common { arg: 42 } }, Opt::from_iter(&["test", "42"]) ); assert!(Opt::clap().get_matches_from_safe(&["test"]).is_err()); assert!(Opt::clap() .get_matches_from_safe(&["test", "42", "24"]) .is_err()); } #[test] #[should_panic] fn flatten_twice() { #[derive(StructOpt, PartialEq, Debug)] struct Common { arg: i32, } #[derive(StructOpt, PartialEq, Debug)] struct Opt { #[structopt(flatten)] c1: Common, // Defines "arg" twice, so this should not work. #[structopt(flatten)] c2: Common, } Opt::from_iter(&["test", "42", "43"]); } #[test] fn flatten_in_subcommand() { #[derive(StructOpt, PartialEq, Debug)] struct Common { arg: i32, } #[derive(StructOpt, PartialEq, Debug)] struct Add { #[structopt(short)] interactive: bool, #[structopt(flatten)] common: Common, } #[derive(StructOpt, PartialEq, Debug)] enum Opt { Fetch { #[structopt(short)] all: bool, #[structopt(flatten)] common: Common, }, Add(Add), } assert_eq!( Opt::Fetch { all: false, common: Common { arg: 42 } }, Opt::from_iter(&["test", "fetch", "42"]) ); assert_eq!( Opt::Add(Add { interactive: true, common: Common { arg: 43 } }), Opt::from_iter(&["test", "add", "-i", "43"]) ); } #[test] fn merge_subcommands_with_flatten() { #[derive(StructOpt, PartialEq, Debug)] enum BaseCli { Command1(Command1), } #[derive(StructOpt, PartialEq, Debug)] struct Command1 { arg1: i32, } #[derive(StructOpt, PartialEq, Debug)] struct Command2 { arg2: i32, } #[derive(StructOpt, PartialEq, Debug)] enum Opt { #[structopt(flatten)] BaseCli(BaseCli), Command2(Command2), } assert_eq!( Opt::BaseCli(BaseCli::Command1(Command1 { arg1: 42 })), Opt::from_iter(&["test", "command1", "42"]) ); assert_eq!( Opt::Command2(Command2 { arg2: 43 }), Opt::from_iter(&["test", "command2", "43"]) ); } #[test] #[should_panic = "structopt misuse: You likely tried to #[flatten] a struct \ that contains #[subcommand]. This is forbidden."] fn subcommand_in_flatten() { #[derive(Debug, StructOpt)] pub enum Struct1 { #[structopt(flatten)] Struct1(Struct2), } #[derive(Debug, StructOpt)] pub struct Struct2 { #[structopt(subcommand)] command_type: Enum3, } #[derive(Debug, StructOpt)] pub enum Enum3 { Command { args: Vec }, } Struct1::from_iter(&["test", "command", "foo"]); } #[test] fn flatten_doc_comment() { #[derive(StructOpt, PartialEq, Debug)] struct Common { /// This is an arg. Arg means "argument". Command line argument. arg: i32, } #[derive(StructOpt, PartialEq, Debug)] struct Opt { /// The very important comment that clippy had me put here. /// It knows better. #[structopt(flatten)] common: Common, } assert_eq!( Opt { common: Common { arg: 42 } }, Opt::from_iter(&["test", "42"]) ); let help = utils::get_help::(); assert!(help.contains("This is an arg.")); assert!(!help.contains("The very important")); } structopt-0.3.26/tests/generics.rs000064400000000000000000000053700072674642500153270ustar 00000000000000use structopt::StructOpt; #[test] fn generic_struct_flatten() { #[derive(StructOpt, PartialEq, Debug)] struct Inner { pub answer: isize, } #[derive(StructOpt, PartialEq, Debug)] struct Outer { #[structopt(flatten)] pub inner: T, } assert_eq!( Outer { inner: Inner { answer: 42 } }, Outer::from_iter(&["--answer", "42"]) ) } #[test] fn generic_struct_flatten_w_where_clause() { #[derive(StructOpt, PartialEq, Debug)] struct Inner { pub answer: isize, } #[derive(StructOpt, PartialEq, Debug)] struct Outer where T: StructOpt, { #[structopt(flatten)] pub inner: T, } assert_eq!( Outer { inner: Inner { answer: 42 } }, Outer::from_iter(&["--answer", "42"]) ) } #[test] fn generic_enum() { #[derive(StructOpt, PartialEq, Debug)] struct Inner { pub answer: isize, } #[derive(StructOpt, PartialEq, Debug)] enum GenericEnum { Start(T), Stop, } assert_eq!( GenericEnum::Start(Inner { answer: 42 }), GenericEnum::from_iter(&["test", "start", "42"]) ) } #[test] fn generic_enum_w_where_clause() { #[derive(StructOpt, PartialEq, Debug)] struct Inner { pub answer: isize, } #[derive(StructOpt, PartialEq, Debug)] enum GenericEnum where T: StructOpt, { Start(T), Stop, } assert_eq!( GenericEnum::Start(Inner { answer: 42 }), GenericEnum::from_iter(&["test", "start", "42"]) ) } #[test] fn generic_w_fromstr_trait_bound() { use std::{fmt, str::FromStr}; #[derive(StructOpt, PartialEq, Debug)] struct Opt where T: FromStr, ::Err: fmt::Debug + fmt::Display, { answer: T, } assert_eq!( Opt:: { answer: 42 }, Opt::::from_iter(&["--answer", "42"]) ) } #[test] fn generic_wo_trait_bound() { use std::time::Duration; #[derive(StructOpt, PartialEq, Debug)] struct Opt { answer: isize, #[structopt(skip)] took: Option, } assert_eq!( Opt:: { answer: 42, took: None }, Opt::::from_iter(&["--answer", "42"]) ) } #[test] fn generic_where_clause_w_trailing_comma() { use std::{fmt, str::FromStr}; #[derive(StructOpt, PartialEq, Debug)] struct Opt where T: FromStr, ::Err: fmt::Debug + fmt::Display, { pub answer: T, } assert_eq!( Opt:: { answer: 42 }, Opt::::from_iter(&["--answer", "42"]) ) } structopt-0.3.26/tests/issues.rs000064400000000000000000000076320072674642500150460ustar 00000000000000// https://github.com/TeXitoi/structopt/issues/{NUMBER} mod utils; use utils::*; use structopt::StructOpt; #[test] fn issue_151() { use structopt::{clap::ArgGroup, StructOpt}; #[derive(StructOpt, Debug)] #[structopt(group = ArgGroup::with_name("verb").required(true).multiple(true))] struct Opt { #[structopt(long, group = "verb")] foo: bool, #[structopt(long, group = "verb")] bar: bool, } #[derive(Debug, StructOpt)] struct Cli { #[structopt(flatten)] a: Opt, } assert!(Cli::clap().get_matches_from_safe(&["test"]).is_err()); assert!(Cli::clap() .get_matches_from_safe(&["test", "--foo"]) .is_ok()); assert!(Cli::clap() .get_matches_from_safe(&["test", "--bar"]) .is_ok()); assert!(Cli::clap() .get_matches_from_safe(&["test", "--zebra"]) .is_err()); assert!(Cli::clap() .get_matches_from_safe(&["test", "--foo", "--bar"]) .is_ok()); } #[test] fn issue_289() { use structopt::{clap::AppSettings, StructOpt}; #[derive(StructOpt)] #[structopt(setting = AppSettings::InferSubcommands)] enum Args { SomeCommand(SubSubCommand), AnotherCommand, } #[derive(StructOpt)] #[structopt(setting = AppSettings::InferSubcommands)] enum SubSubCommand { TestCommand, } assert!(Args::clap() .get_matches_from_safe(&["test", "some-command", "test-command"]) .is_ok()); assert!(Args::clap() .get_matches_from_safe(&["test", "some", "test-command"]) .is_ok()); assert!(Args::clap() .get_matches_from_safe(&["test", "some-command", "test"]) .is_ok()); assert!(Args::clap() .get_matches_from_safe(&["test", "some", "test"]) .is_ok()); } #[test] fn issue_324() { fn my_version() -> &'static str { "MY_VERSION" } #[derive(StructOpt)] #[structopt(version = my_version())] struct Opt { #[structopt(subcommand)] _cmd: Option, } #[derive(StructOpt)] enum SubCommand { Start, } let help = get_long_help::(); assert!(help.contains("MY_VERSION")); } #[test] fn issue_359() { #[derive(Debug, PartialEq, StructOpt)] struct Opt { #[structopt(subcommand)] sub: Subcommands, } #[derive(Debug, PartialEq, StructOpt)] enum Subcommands { Add, #[structopt(external_subcommand)] Other(Vec), } assert_eq!( Opt { sub: Subcommands::Other(vec!["only_one_arg".into()]) }, Opt::from_iter(&["test", "only_one_arg"]) ); } #[test] fn issue_418() { use structopt::StructOpt; #[derive(Debug, StructOpt)] struct Opts { #[structopt(subcommand)] /// The command to run command: Command, } #[derive(Debug, StructOpt)] enum Command { /// Reticulate the splines #[structopt(visible_alias = "ret")] Reticulate { /// How many splines num_splines: u8, }, /// Frobnicate the rest #[structopt(visible_alias = "frob")] Frobnicate, } let help = get_long_help::(); assert!(help.contains("Reticulate the splines [aliases: ret]")); } #[test] fn issue_490() { use std::iter::FromIterator; use std::str::FromStr; use structopt::StructOpt; struct U16ish; impl FromStr for U16ish { type Err = (); fn from_str(_: &str) -> Result { unimplemented!() } } impl<'a> FromIterator<&'a U16ish> for Vec { fn from_iter>(_: T) -> Self { unimplemented!() } } #[derive(StructOpt, Debug)] struct Opt { opt_vec: Vec, #[structopt(long)] opt_opt_vec: Option>, } // Assert that it compiles } structopt-0.3.26/tests/macro-errors.rs000064400000000000000000000007540072674642500161440ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed #[rustversion::attr(any(not(stable), before(1.54)), ignore)] #[test] fn ui() { let t = trybuild::TestCases::new(); t.compile_fail("tests/ui/*.rs"); } structopt-0.3.26/tests/nested-subcommands.rs000064400000000000000000000106730072674642500173250ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(StructOpt, PartialEq, Debug)] struct Opt { #[structopt(short, long)] force: bool, #[structopt(short, long, parse(from_occurrences))] verbose: u64, #[structopt(subcommand)] cmd: Sub, } #[derive(StructOpt, PartialEq, Debug)] enum Sub { Fetch {}, Add {}, } #[derive(StructOpt, PartialEq, Debug)] struct Opt2 { #[structopt(short, long)] force: bool, #[structopt(short, long, parse(from_occurrences))] verbose: u64, #[structopt(subcommand)] cmd: Option, } #[test] fn test_no_cmd() { let result = Opt::clap().get_matches_from_safe(&["test"]); assert!(result.is_err()); assert_eq!( Opt2 { force: false, verbose: 0, cmd: None }, Opt2::from_clap(&Opt2::clap().get_matches_from(&["test"])) ); } #[test] fn test_fetch() { assert_eq!( Opt { force: false, verbose: 3, cmd: Sub::Fetch {} }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-vvv", "fetch"])) ); assert_eq!( Opt { force: true, verbose: 0, cmd: Sub::Fetch {} }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--force", "fetch"])) ); } #[test] fn test_add() { assert_eq!( Opt { force: false, verbose: 0, cmd: Sub::Add {} }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "add"])) ); assert_eq!( Opt { force: false, verbose: 2, cmd: Sub::Add {} }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-vv", "add"])) ); } #[test] fn test_badinput() { let result = Opt::clap().get_matches_from_safe(&["test", "badcmd"]); assert!(result.is_err()); let result = Opt::clap().get_matches_from_safe(&["test", "add", "--verbose"]); assert!(result.is_err()); let result = Opt::clap().get_matches_from_safe(&["test", "--badopt", "add"]); assert!(result.is_err()); let result = Opt::clap().get_matches_from_safe(&["test", "add", "--badopt"]); assert!(result.is_err()); } #[derive(StructOpt, PartialEq, Debug)] struct Opt3 { #[structopt(short, long)] all: bool, #[structopt(subcommand)] cmd: Sub2, } #[derive(StructOpt, PartialEq, Debug)] enum Sub2 { Foo { file: String, #[structopt(subcommand)] cmd: Sub3, }, Bar {}, } #[derive(StructOpt, PartialEq, Debug)] enum Sub3 { Baz {}, Quux {}, } #[test] fn test_subsubcommand() { assert_eq!( Opt3 { all: true, cmd: Sub2::Foo { file: "lib.rs".to_string(), cmd: Sub3::Quux {} } }, Opt3::from_clap( &Opt3::clap().get_matches_from(&["test", "--all", "foo", "lib.rs", "quux"]) ) ); } #[derive(StructOpt, PartialEq, Debug)] enum SubSubCmdWithOption { Remote { #[structopt(subcommand)] cmd: Option, }, Stash { #[structopt(subcommand)] cmd: Stash, }, } #[derive(StructOpt, PartialEq, Debug)] enum Remote { Add { name: String, url: String }, Remove { name: String }, } #[derive(StructOpt, PartialEq, Debug)] enum Stash { Save, Pop, } #[test] fn sub_sub_cmd_with_option() { fn make(args: &[&str]) -> Option { SubSubCmdWithOption::clap() .get_matches_from_safe(args) .ok() .map(|m| SubSubCmdWithOption::from_clap(&m)) } assert_eq!( Some(SubSubCmdWithOption::Remote { cmd: None }), make(&["", "remote"]) ); assert_eq!( Some(SubSubCmdWithOption::Remote { cmd: Some(Remote::Add { name: "origin".into(), url: "http".into() }) }), make(&["", "remote", "add", "origin", "http"]) ); assert_eq!( Some(SubSubCmdWithOption::Stash { cmd: Stash::Save }), make(&["", "stash", "save"]) ); assert_eq!(None, make(&["", "stash"])); } structopt-0.3.26/tests/non_literal_attributes.rs000064400000000000000000000076130072674642500203060ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::clap::AppSettings; use structopt::StructOpt; pub const DISPLAY_ORDER: usize = 2; // Check if the global settings compile #[derive(StructOpt, Debug, PartialEq, Eq)] #[structopt(global_settings = &[AppSettings::ColoredHelp])] struct Opt { #[structopt( long = "x", display_order = DISPLAY_ORDER, next_line_help = true, default_value = "0", require_equals = true )] x: i32, #[structopt(short = "l", long = "level", aliases = &["set-level", "lvl"])] level: String, #[structopt(long("values"))] values: Vec, #[structopt(name = "FILE", requires_if("FILE", "values"))] files: Vec, } #[test] fn test_slice() { assert_eq!( Opt { x: 0, level: "1".to_string(), files: Vec::new(), values: vec![], }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-l", "1"])) ); assert_eq!( Opt { x: 0, level: "1".to_string(), files: Vec::new(), values: vec![], }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--level", "1"])) ); assert_eq!( Opt { x: 0, level: "1".to_string(), files: Vec::new(), values: vec![], }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--set-level", "1"])) ); assert_eq!( Opt { x: 0, level: "1".to_string(), files: Vec::new(), values: vec![], }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--lvl", "1"])) ); } #[test] fn test_multi_args() { assert_eq!( Opt { x: 0, level: "1".to_string(), files: vec!["file".to_string()], values: vec![], }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-l", "1", "file"])) ); assert_eq!( Opt { x: 0, level: "1".to_string(), files: vec!["FILE".to_string()], values: vec![1], }, Opt::from_clap( &Opt::clap().get_matches_from(&["test", "-l", "1", "--values", "1", "--", "FILE"]), ) ); } #[test] fn test_multi_args_fail() { let result = Opt::clap().get_matches_from_safe(&["test", "-l", "1", "--", "FILE"]); assert!(result.is_err()); } #[test] fn test_bool() { assert_eq!( Opt { x: 1, level: "1".to_string(), files: vec![], values: vec![], }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-l", "1", "--x=1"])) ); let result = Opt::clap().get_matches_from_safe(&["test", "-l", "1", "--x", "1"]); assert!(result.is_err()); } fn parse_hex(input: &str) -> Result { u64::from_str_radix(input, 16) } #[derive(StructOpt, PartialEq, Debug)] struct HexOpt { #[structopt(short = "n", parse(try_from_str = parse_hex))] number: u64, } #[test] fn test_parse_hex_function_path() { assert_eq!( HexOpt { number: 5 }, HexOpt::from_clap(&HexOpt::clap().get_matches_from(&["test", "-n", "5"])) ); assert_eq!( HexOpt { number: 0xabcdef }, HexOpt::from_clap(&HexOpt::clap().get_matches_from(&["test", "-n", "abcdef"])) ); let err = HexOpt::clap() .get_matches_from_safe(&["test", "-n", "gg"]) .unwrap_err(); assert!( err.message.contains("invalid digit found in string"), "{}", err ); } structopt-0.3.26/tests/options.rs000064400000000000000000000204670072674642500152270ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[test] fn required_option() { #[derive(StructOpt, PartialEq, Debug)] struct Opt { #[structopt(short, long)] arg: i32, } assert_eq!( Opt { arg: 42 }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a42"])) ); assert_eq!( Opt { arg: 42 }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "42"])) ); assert_eq!( Opt { arg: 42 }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--arg", "42"])) ); assert!(Opt::clap().get_matches_from_safe(&["test"]).is_err()); assert!(Opt::clap() .get_matches_from_safe(&["test", "-a42", "-a24"]) .is_err()); } #[test] fn optional_option() { #[derive(StructOpt, PartialEq, Debug)] struct Opt { #[structopt(short)] arg: Option, } assert_eq!( Opt { arg: Some(42) }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a42"])) ); assert_eq!( Opt { arg: None }, Opt::from_clap(&Opt::clap().get_matches_from(&["test"])) ); assert!(Opt::clap() .get_matches_from_safe(&["test", "-a42", "-a24"]) .is_err()); } #[test] fn option_with_default() { #[derive(StructOpt, PartialEq, Debug)] struct Opt { #[structopt(short, default_value = "42")] arg: i32, } assert_eq!( Opt { arg: 24 }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a24"])) ); assert_eq!( Opt { arg: 42 }, Opt::from_clap(&Opt::clap().get_matches_from(&["test"])) ); assert!(Opt::clap() .get_matches_from_safe(&["test", "-a42", "-a24"]) .is_err()); } #[test] fn option_with_raw_default() { #[derive(StructOpt, PartialEq, Debug)] struct Opt { #[structopt(short, default_value = "42")] arg: i32, } assert_eq!( Opt { arg: 24 }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a24"])) ); assert_eq!( Opt { arg: 42 }, Opt::from_clap(&Opt::clap().get_matches_from(&["test"])) ); assert!(Opt::clap() .get_matches_from_safe(&["test", "-a42", "-a24"]) .is_err()); } #[test] fn options() { #[derive(StructOpt, PartialEq, Debug)] struct Opt { #[structopt(short, long)] arg: Vec, } assert_eq!( Opt { arg: vec![24] }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a24"])) ); assert_eq!( Opt { arg: vec![] }, Opt::from_clap(&Opt::clap().get_matches_from(&["test"])) ); assert_eq!( Opt { arg: vec![24, 42] }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a24", "--arg", "42"])) ); } #[test] fn empy_default_value() { #[derive(StructOpt, PartialEq, Debug)] struct Opt { #[structopt(short, default_value = "")] arg: String, } assert_eq!(Opt { arg: "".into() }, Opt::from_iter(&["test"])); assert_eq!( Opt { arg: "foo".into() }, Opt::from_iter(&["test", "-afoo"]) ); } #[test] fn option_from_str() { #[derive(Debug, PartialEq)] struct A; impl<'a> From<&'a str> for A { fn from(_: &str) -> A { A } } #[derive(Debug, StructOpt, PartialEq)] struct Opt { #[structopt(parse(from_str))] a: Option, } assert_eq!(Opt { a: None }, Opt::from_iter(&["test"])); assert_eq!(Opt { a: Some(A) }, Opt::from_iter(&["test", "foo"])); } #[test] fn optional_argument_for_optional_option() { #[derive(StructOpt, PartialEq, Debug)] struct Opt { #[structopt(short)] #[allow(clippy::option_option)] arg: Option>, } assert_eq!( Opt { arg: Some(Some(42)) }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a42"])) ); assert_eq!( Opt { arg: Some(None) }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a"])) ); assert_eq!( Opt { arg: None }, Opt::from_clap(&Opt::clap().get_matches_from(&["test"])) ); assert!(Opt::clap() .get_matches_from_safe(&["test", "-a42", "-a24"]) .is_err()); } #[test] fn two_option_options() { #[derive(StructOpt, PartialEq, Debug)] #[allow(clippy::option_option)] struct Opt { #[structopt(short)] arg: Option>, #[structopt(long)] field: Option>, } assert_eq!( Opt { arg: Some(Some(42)), field: Some(Some("f".into())) }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a42", "--field", "f"])) ); assert_eq!( Opt { arg: Some(Some(42)), field: Some(None) }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a42", "--field"])) ); assert_eq!( Opt { arg: Some(None), field: Some(None) }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "--field"])) ); assert_eq!( Opt { arg: Some(None), field: Some(Some("f".into())) }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "--field", "f"])) ); assert_eq!( Opt { arg: None, field: Some(None) }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--field"])) ); assert_eq!( Opt { arg: None, field: None }, Opt::from_clap(&Opt::clap().get_matches_from(&["test"])) ); } #[test] fn optional_vec() { #[derive(StructOpt, PartialEq, Debug)] struct Opt { #[structopt(short)] arg: Option>, } assert_eq!( Opt { arg: Some(vec![1]) }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "1"])) ); assert_eq!( Opt { arg: Some(vec![1, 2]) }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a1", "-a2"])) ); assert_eq!( Opt { arg: Some(vec![1, 2]) }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a1", "-a2", "-a"])) ); assert_eq!( Opt { arg: Some(vec![1, 2]) }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a1", "-a", "-a2"])) ); assert_eq!( Opt { arg: Some(vec![1, 2]) }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "1", "2"])) ); assert_eq!( Opt { arg: Some(vec![1, 2, 3]) }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "1", "2", "-a", "3"])) ); assert_eq!( Opt { arg: Some(vec![]) }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a"])) ); assert_eq!( Opt { arg: Some(vec![]) }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "-a"])) ); assert_eq!( Opt { arg: None }, Opt::from_clap(&Opt::clap().get_matches_from(&["test"])) ); } #[test] fn two_optional_vecs() { #[derive(StructOpt, PartialEq, Debug)] struct Opt { #[structopt(short)] arg: Option>, #[structopt(short)] b: Option>, } assert_eq!( Opt { arg: Some(vec![1]), b: Some(vec![]) }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "1", "-b"])) ); assert_eq!( Opt { arg: Some(vec![1]), b: Some(vec![]) }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "-b", "-a1"])) ); assert_eq!( Opt { arg: Some(vec![1, 2]), b: Some(vec![1, 2]) }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a1", "-a2", "-b1", "-b2"])) ); assert_eq!( Opt { arg: None, b: None }, Opt::from_clap(&Opt::clap().get_matches_from(&["test"])) ); } structopt-0.3.26/tests/privacy.rs000064400000000000000000000014340072674642500152020ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; mod options { use super::StructOpt; #[derive(Debug, StructOpt)] pub struct Options { #[structopt(subcommand)] pub subcommand: super::subcommands::SubCommand, } } mod subcommands { use super::StructOpt; #[derive(Debug, StructOpt)] pub enum SubCommand { /// foo Foo { /// foo bars: Vec, }, } } structopt-0.3.26/tests/raw_bool_literal.rs000064400000000000000000000014560072674642500170510ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[test] fn raw_bool_literal() { #[derive(StructOpt, Debug, PartialEq)] #[structopt(no_version, name = "raw_bool")] struct Opt { #[structopt(raw(false))] a: String, #[structopt(raw(true))] b: String, } assert_eq!( Opt { a: "one".into(), b: "--help".into() }, Opt::from_iter(&["test", "one", "--", "--help"]) ); } structopt-0.3.26/tests/raw_idents.rs000064400000000000000000000005440072674642500156650ustar 00000000000000use structopt::StructOpt; #[test] fn raw_idents() { #[derive(StructOpt, Debug, PartialEq)] struct Opt { #[structopt(short, long)] r#type: Vec, } assert_eq!( Opt { r#type: vec!["long".into(), "short".into()] }, Opt::from_iter(&["test", "--type", "long", "-t", "short"]) ); } structopt-0.3.26/tests/regressions.rs000064400000000000000000000016010072674642500160640ustar 00000000000000use structopt::StructOpt; mod utils; use utils::*; #[test] fn invisible_group_issue_439() { macro_rules! m { ($bool:ty) => { #[derive(Debug, StructOpt)] struct Opts { #[structopt(long = "x")] x: $bool, } }; } m!(bool); let help = get_long_help::(); assert!(help.contains("--x")); assert!(!help.contains("--x ")); Opts::from_iter_safe(&["test", "--x"]).unwrap(); } #[test] fn issue_447() { macro_rules! Command { ( $name:ident, [ #[$meta:meta] $var:ident($inner:ty) ] ) => { #[derive(Debug, PartialEq, structopt::StructOpt)] enum $name { #[$meta] $var($inner), } }; } Command! {GitCmd, [ #[structopt(external_subcommand)] Ext(Vec) ]} } structopt-0.3.26/tests/rename_all_env.rs000064400000000000000000000020020072674642500164640ustar 00000000000000mod utils; use structopt::StructOpt; use utils::*; #[test] fn it_works() { #[derive(Debug, PartialEq, StructOpt)] #[structopt(rename_all_env = "kebab")] struct BehaviorModel { #[structopt(env)] be_nice: String, } let help = get_help::(); assert!(help.contains("[env: be-nice=]")); } #[test] fn default_is_screaming() { #[derive(Debug, PartialEq, StructOpt)] struct BehaviorModel { #[structopt(env)] be_nice: String, } let help = get_help::(); assert!(help.contains("[env: BE_NICE=]")); } #[test] fn overridable() { #[derive(Debug, PartialEq, StructOpt)] #[structopt(rename_all_env = "kebab")] struct BehaviorModel { #[structopt(env)] be_nice: String, #[structopt(rename_all_env = "pascal", env)] be_agressive: String, } let help = get_help::(); assert!(help.contains("[env: be-nice=]")); assert!(help.contains("[env: BeAgressive=]")); } structopt-0.3.26/tests/skip.rs000064400000000000000000000057160072674642500145020ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[test] fn skip_1() { #[derive(StructOpt, Debug, PartialEq)] struct Opt { #[structopt(short)] x: u32, #[structopt(skip)] s: u32, } assert!(Opt::from_iter_safe(&["test", "-x", "10", "20"]).is_err()); assert_eq!( Opt::from_iter(&["test", "-x", "10"]), Opt { x: 10, s: 0, // default } ); } #[test] fn skip_2() { #[derive(StructOpt, Debug, PartialEq)] struct Opt { #[structopt(short)] x: u32, #[structopt(skip)] ss: String, #[structopt(skip)] sn: u8, y: u32, #[structopt(skip)] sz: u16, t: u32, } assert_eq!( Opt::from_iter(&["test", "-x", "10", "20", "30"]), Opt { x: 10, ss: String::from(""), sn: 0, y: 20, sz: 0, t: 30, } ); } #[test] fn skip_enum() { #[derive(Debug, PartialEq)] #[allow(unused)] enum Kind { A, B, } impl Default for Kind { fn default() -> Self { return Kind::B; } } #[derive(StructOpt, Debug, PartialEq)] pub struct Opt { #[structopt(long, short)] number: u32, #[structopt(skip)] k: Kind, #[structopt(skip)] v: Vec, } assert_eq!( Opt::from_iter(&["test", "-n", "10"]), Opt { number: 10, k: Kind::B, v: vec![], } ); } #[test] fn skip_help_doc_comments() { #[derive(StructOpt, Debug, PartialEq)] pub struct Opt { #[structopt(skip, help = "internal_stuff")] a: u32, #[structopt(skip, long_help = "internal_stuff\ndo not touch")] b: u32, /// Not meant to be used by clap. /// /// I want a default here. #[structopt(skip)] c: u32, #[structopt(short, parse(try_from_str))] n: u32, } assert_eq!( Opt::from_iter(&["test", "-n", "10"]), Opt { n: 10, a: 0, b: 0, c: 0, } ); } #[test] fn skip_val() { #[derive(StructOpt, Debug, PartialEq)] pub struct Opt { #[structopt(long, short)] number: u32, #[structopt(skip = "key")] k: String, #[structopt(skip = vec![1, 2, 3])] v: Vec, } assert_eq!( Opt::from_iter(&["test", "-n", "10"]), Opt { number: 10, k: "key".into(), v: vec![1, 2, 3] } ); } structopt-0.3.26/tests/special_types.rs000064400000000000000000000030030072674642500163630ustar 00000000000000//! Checks that types like `::std::option::Option` are not special use structopt::StructOpt; #[rustversion::since(1.37)] #[test] fn special_types_bool() { mod inner { #[allow(non_camel_case_types)] #[derive(PartialEq, Debug)] pub struct bool(pub String); impl std::str::FromStr for self::bool { type Err = String; fn from_str(s: &str) -> Result { Ok(self::bool(s.into())) } } } #[derive(StructOpt, PartialEq, Debug)] struct Opt { arg: inner::bool, } assert_eq!( Opt { arg: inner::bool("success".into()) }, Opt::from_iter(&["test", "success"]) ); } #[test] fn special_types_option() { fn parser(s: &str) -> Option { Some(s.to_string()) } #[derive(StructOpt, PartialEq, Debug)] struct Opt { #[structopt(parse(from_str = parser))] arg: ::std::option::Option, } assert_eq!( Opt { arg: Some("success".into()) }, Opt::from_iter(&["test", "success"]) ); } #[test] fn special_types_vec() { fn parser(s: &str) -> Vec { vec![s.to_string()] } #[derive(StructOpt, PartialEq, Debug)] struct Opt { #[structopt(parse(from_str = parser))] arg: ::std::vec::Vec, } assert_eq!( Opt { arg: vec!["success".into()] }, Opt::from_iter(&["test", "success"]) ); } structopt-0.3.26/tests/subcommands.rs000064400000000000000000000173120072674642500160420ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. mod utils; use structopt::StructOpt; use utils::*; #[derive(StructOpt, PartialEq, Debug)] enum Opt { /// Fetch stuff from GitHub Fetch { #[structopt(long)] all: bool, #[structopt(short, long)] /// Overwrite local branches. force: bool, repo: String, }, Add { #[structopt(short, long)] interactive: bool, #[structopt(short, long)] verbose: bool, }, } #[test] fn test_fetch() { assert_eq!( Opt::Fetch { all: true, force: false, repo: "origin".to_string() }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "fetch", "--all", "origin"])) ); assert_eq!( Opt::Fetch { all: false, force: true, repo: "origin".to_string() }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "fetch", "-f", "origin"])) ); } #[test] fn test_add() { assert_eq!( Opt::Add { interactive: false, verbose: false }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "add"])) ); assert_eq!( Opt::Add { interactive: true, verbose: true }, Opt::from_clap(&Opt::clap().get_matches_from(&["test", "add", "-i", "-v"])) ); } #[test] fn test_no_parse() { let result = Opt::clap().get_matches_from_safe(&["test", "badcmd", "-i", "-v"]); assert!(result.is_err()); let result = Opt::clap().get_matches_from_safe(&["test", "add", "--badoption"]); assert!(result.is_err()); let result = Opt::clap().get_matches_from_safe(&["test"]); assert!(result.is_err()); } #[derive(StructOpt, PartialEq, Debug)] enum Opt2 { DoSomething { arg: String }, } #[test] /// This test is specifically to make sure that hyphenated subcommands get /// processed correctly. fn test_hyphenated_subcommands() { assert_eq!( Opt2::DoSomething { arg: "blah".to_string() }, Opt2::from_clap(&Opt2::clap().get_matches_from(&["test", "do-something", "blah"])) ); } #[derive(StructOpt, PartialEq, Debug)] enum Opt3 { Add, Init, Fetch, } #[test] fn test_null_commands() { assert_eq!( Opt3::Add, Opt3::from_clap(&Opt3::clap().get_matches_from(&["test", "add"])) ); assert_eq!( Opt3::Init, Opt3::from_clap(&Opt3::clap().get_matches_from(&["test", "init"])) ); assert_eq!( Opt3::Fetch, Opt3::from_clap(&Opt3::clap().get_matches_from(&["test", "fetch"])) ); } #[derive(StructOpt, PartialEq, Debug)] #[structopt(about = "Not shown")] struct Add { file: String, } /// Not shown #[derive(StructOpt, PartialEq, Debug)] struct Fetch { remote: String, } #[derive(StructOpt, PartialEq, Debug)] enum Opt4 { // Not shown /// Add a file Add(Add), Init, /// download history from remote Fetch(Fetch), } #[test] fn test_tuple_commands() { assert_eq!( Opt4::Add(Add { file: "f".to_string() }), Opt4::from_clap(&Opt4::clap().get_matches_from(&["test", "add", "f"])) ); assert_eq!( Opt4::Init, Opt4::from_clap(&Opt4::clap().get_matches_from(&["test", "init"])) ); assert_eq!( Opt4::Fetch(Fetch { remote: "origin".to_string() }), Opt4::from_clap(&Opt4::clap().get_matches_from(&["test", "fetch", "origin"])) ); let output = get_long_help::(); assert!(output.contains("download history from remote")); assert!(output.contains("Add a file")); assert!(!output.contains("Not shown")); } #[test] fn enum_in_enum_subsubcommand() { #[derive(StructOpt, Debug, PartialEq)] pub enum Opt { Daemon(DaemonCommand), } #[derive(StructOpt, Debug, PartialEq)] pub enum DaemonCommand { Start, Stop, } let result = Opt::clap().get_matches_from_safe(&["test"]); assert!(result.is_err()); let result = Opt::clap().get_matches_from_safe(&["test", "daemon"]); assert!(result.is_err()); let result = Opt::from_iter(&["test", "daemon", "start"]); assert_eq!(Opt::Daemon(DaemonCommand::Start), result); } #[test] fn flatten_enum() { #[derive(StructOpt, Debug, PartialEq)] struct Opt { #[structopt(flatten)] sub_cmd: SubCmd, } #[derive(StructOpt, Debug, PartialEq)] enum SubCmd { Foo, Bar, } assert!(Opt::from_iter_safe(&["test"]).is_err()); assert_eq!( Opt::from_iter(&["test", "foo"]), Opt { sub_cmd: SubCmd::Foo } ); } #[test] fn external_subcommand() { #[derive(Debug, PartialEq, StructOpt)] struct Opt { #[structopt(subcommand)] sub: Subcommands, } #[derive(Debug, PartialEq, StructOpt)] enum Subcommands { Add, Remove, #[structopt(external_subcommand)] Other(Vec), } assert_eq!( Opt::from_iter(&["test", "add"]), Opt { sub: Subcommands::Add } ); assert_eq!( Opt::from_iter(&["test", "remove"]), Opt { sub: Subcommands::Remove } ); assert_eq!( Opt::from_iter(&["test", "git", "status"]), Opt { sub: Subcommands::Other(vec!["git".into(), "status".into()]) } ); assert!(Opt::from_iter_safe(&["test"]).is_err()); } #[test] fn external_subcommand_os_string() { use std::ffi::OsString; #[derive(Debug, PartialEq, StructOpt)] struct Opt { #[structopt(subcommand)] sub: Subcommands, } #[derive(Debug, PartialEq, StructOpt)] enum Subcommands { #[structopt(external_subcommand)] Other(Vec), } assert_eq!( Opt::from_iter(&["test", "git", "status"]), Opt { sub: Subcommands::Other(vec!["git".into(), "status".into()]) } ); assert!(Opt::from_iter_safe(&["test"]).is_err()); } #[test] fn external_subcommand_optional() { #[derive(Debug, PartialEq, StructOpt)] struct Opt { #[structopt(subcommand)] sub: Option, } #[derive(Debug, PartialEq, StructOpt)] enum Subcommands { #[structopt(external_subcommand)] Other(Vec), } assert_eq!( Opt::from_iter(&["test", "git", "status"]), Opt { sub: Some(Subcommands::Other(vec!["git".into(), "status".into()])) } ); assert_eq!(Opt::from_iter(&["test"]), Opt { sub: None }); } #[test] fn skip_subcommand() { #[derive(Debug, PartialEq, StructOpt)] struct Opt { #[structopt(subcommand)] sub: Subcommands, } #[derive(Debug, PartialEq, StructOpt)] enum Subcommands { Add, Remove, #[allow(dead_code)] #[structopt(skip)] Skip, } assert_eq!( Opt::from_iter(&["test", "add"]), Opt { sub: Subcommands::Add } ); assert_eq!( Opt::from_iter(&["test", "remove"]), Opt { sub: Subcommands::Remove } ); let res = Opt::from_iter_safe(&["test", "skip"]); assert!( matches!( res, Err(clap::Error { kind: clap::ErrorKind::UnknownArgument, .. }) ), "Unexpected result: {:?}", res ); } structopt-0.3.26/tests/ui/bool_default_value.rs000064400000000000000000000011320072674642500177700ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "basic")] struct Opt { #[structopt(short, default_value = true)] b: bool, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/bool_default_value.stderr000064400000000000000000000002660072674642500206560ustar 00000000000000error: default_value is meaningless for bool --> $DIR/bool_default_value.rs:14:24 | 14 | #[structopt(short, default_value = true)] | ^^^^^^^^^^^^^ structopt-0.3.26/tests/ui/bool_required.rs000064400000000000000000000011250072674642500167720ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "basic")] struct Opt { #[structopt(short, required = true)] b: bool, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/bool_required.stderr000064400000000000000000000002420072674642500176500ustar 00000000000000error: required is meaningless for bool --> $DIR/bool_required.rs:14:24 | 14 | #[structopt(short, required = true)] | ^^^^^^^^ structopt-0.3.26/tests/ui/enum_flatten.rs000064400000000000000000000011050072674642500166160ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "basic")] enum Opt { #[structopt(flatten)] Variant1, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/enum_flatten.stderr000064400000000000000000000002600072674642500174760ustar 00000000000000error: `flatten` is usable only with single-typed tuple variants --> $DIR/enum_flatten.rs:14:5 | 14 | / #[structopt(flatten)] 15 | | Variant1, | |____________^ structopt-0.3.26/tests/ui/external_subcommand_wrong_type.rs000064400000000000000000000005010072674642500224430ustar 00000000000000use structopt::StructOpt; use std::ffi::CString; #[derive(StructOpt, Debug)] struct Opt { #[structopt(subcommand)] cmd: Command, } #[derive(StructOpt, Debug)] enum Command { #[structopt(external_subcommand)] Other(Vec) } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); }structopt-0.3.26/tests/ui/external_subcommand_wrong_type.stderr000064400000000000000000000004340072674642500233270ustar 00000000000000error[E0308]: mismatched types --> $DIR/external_subcommand_wrong_type.rs:13:15 | 13 | Other(Vec) | ^^^^^^^ expected struct `CString`, found struct `OsString` | = note: expected struct `Vec` found struct `Vec` structopt-0.3.26/tests/ui/flatten_and_methods.rs000064400000000000000000000013360072674642500201450ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(StructOpt, Debug)] struct DaemonOpts { #[structopt(short)] user: String, #[structopt(short)] group: String, } #[derive(StructOpt, Debug)] #[structopt(name = "basic")] struct Opt { #[structopt(short, flatten)] opts: DaemonOpts, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/flatten_and_methods.stderr000064400000000000000000000002520072674642500210200ustar 00000000000000error: methods are not allowed for flattened entry --> $DIR/flatten_and_methods.rs:22:24 | 22 | #[structopt(short, flatten)] | ^^^^^^^ structopt-0.3.26/tests/ui/flatten_and_parse.rs000064400000000000000000000013600072674642500176110ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(StructOpt, Debug)] struct DaemonOpts { #[structopt(short)] user: String, #[structopt(short)] group: String, } #[derive(StructOpt, Debug)] #[structopt(name = "basic")] struct Opt { #[structopt(flatten, parse(from_occurrences))] opts: DaemonOpts, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/flatten_and_parse.stderr000064400000000000000000000003010072674642500204620ustar 00000000000000error: parse attribute is not allowed for flattened entry --> $DIR/flatten_and_parse.rs:22:26 | 22 | #[structopt(flatten, parse(from_occurrences))] | ^^^^^ structopt-0.3.26/tests/ui/multiple_external_subcommand.rs000064400000000000000000000005470072674642500221130ustar 00000000000000use structopt::StructOpt; #[derive(StructOpt, Debug)] struct Opt { #[structopt(subcommand)] cmd: Command, } #[derive(StructOpt, Debug)] enum Command { #[structopt(external_subcommand)] Run(Vec), #[structopt(external_subcommand)] Other(Vec) } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/multiple_external_subcommand.stderr000064400000000000000000000003370072674642500227670ustar 00000000000000error: Only one variant can be marked with `external_subcommand`, this is the second --> $DIR/multiple_external_subcommand.rs:14:17 | 14 | #[structopt(external_subcommand)] | ^^^^^^^^^^^^^^^^^^^ structopt-0.3.26/tests/ui/non_existent_attr.rs000064400000000000000000000011440072674642500177070ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "basic")] struct Opt { #[structopt(short, non_existing_attribute = 1)] debug: bool, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/non_existent_attr.stderr000064400000000000000000000004340072674642500205670ustar 00000000000000error[E0599]: no method named `non_existing_attribute` found for struct `Arg` in the current scope --> $DIR/non_existent_attr.rs:14:24 | 14 | #[structopt(short, non_existing_attribute = 1)] | ^^^^^^^^^^^^^^^^^^^^^^ method not found in `Arg<'_, '_>` structopt-0.3.26/tests/ui/opt_opt_nonpositional.rs000064400000000000000000000010730072674642500206010ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "basic")] struct Opt { n: Option>, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/opt_opt_nonpositional.stderr000064400000000000000000000002640072674642500214610ustar 00000000000000error: Option> type is meaningless for positional argument --> $DIR/opt_opt_nonpositional.rs:14:8 | 14 | n: Option>, | ^^^^^^^^^^^^^^^^^^^ structopt-0.3.26/tests/ui/opt_vec_nonpositional.rs000064400000000000000000000010700072674642500205510ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "basic")] struct Opt { n: Option>, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/opt_vec_nonpositional.stderr000064400000000000000000000002530072674642500214320ustar 00000000000000error: Option> type is meaningless for positional argument --> $DIR/opt_vec_nonpositional.rs:14:8 | 14 | n: Option>, | ^^^^^^^^^^^^^^^^ structopt-0.3.26/tests/ui/option_default_value.rs000064400000000000000000000011360072674642500203510ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "basic")] struct Opt { #[structopt(short, default_value = 1)] n: Option, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/option_default_value.stderr000064400000000000000000000002670072674642500212340ustar 00000000000000error: default_value is meaningless for Option --> $DIR/option_default_value.rs:14:24 | 14 | #[structopt(short, default_value = 1)] | ^^^^^^^^^^^^^ structopt-0.3.26/tests/ui/option_required.rs000064400000000000000000000011340072674642500173470ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "basic")] struct Opt { #[structopt(short, required = true)] n: Option, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/option_required.stderr000064400000000000000000000002460072674642500202310ustar 00000000000000error: required is meaningless for Option --> $DIR/option_required.rs:14:24 | 14 | #[structopt(short, required = true)] | ^^^^^^^^ structopt-0.3.26/tests/ui/parse_empty_try_from_os.rs000064400000000000000000000011270072674642500211130ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "basic")] struct Opt { #[structopt(parse(try_from_os_str))] s: String, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/parse_empty_try_from_os.stderr000064400000000000000000000003060072674642500217700ustar 00000000000000error: you must set parser for `try_from_os_str` explicitly --> $DIR/parse_empty_try_from_os.rs:14:23 | 14 | #[structopt(parse(try_from_os_str))] | ^^^^^^^^^^^^^^^ structopt-0.3.26/tests/ui/parse_function_is_not_path.rs000064400000000000000000000011260072674642500215460ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "basic")] struct Opt { #[structopt(parse(from_str = "2"))] s: String, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/parse_function_is_not_path.stderr000064400000000000000000000002730072674642500224270ustar 00000000000000error: `parse` argument must be a function path --> $DIR/parse_function_is_not_path.rs:14:34 | 14 | #[structopt(parse(from_str = "2"))] | ^^^ structopt-0.3.26/tests/ui/parse_literal_spec.rs000064400000000000000000000011220072674642500177740ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "basic")] struct Opt { #[structopt(parse("from_str"))] s: String, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/parse_literal_spec.stderr000064400000000000000000000002620072674642500206570ustar 00000000000000error: parser specification must start with identifier --> $DIR/parse_literal_spec.rs:14:23 | 14 | #[structopt(parse("from_str"))] | ^^^^^^^^^^ structopt-0.3.26/tests/ui/parse_not_zero_args.rs000064400000000000000000000011320072674642500202020ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "basic")] struct Opt { #[structopt(parse(from_str, from_str))] s: String, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/parse_not_zero_args.stderr000064400000000000000000000002470072674642500210670ustar 00000000000000error: `parse` must have exactly one argument --> $DIR/parse_not_zero_args.rs:14:17 | 14 | #[structopt(parse(from_str, from_str))] | ^^^^^ structopt-0.3.26/tests/ui/positional_bool.rs000064400000000000000000000001750072674642500173370ustar 00000000000000use structopt::StructOpt; #[derive(StructOpt, Debug)] struct Opt { verbose: bool, } fn main() { Opt::from_args(); }structopt-0.3.26/tests/ui/positional_bool.stderr000064400000000000000000000006440072674642500202170ustar 00000000000000error: `bool` cannot be used as positional parameter with default parser = help: if you want to create a flag add `long` or `short` = help: If you really want a boolean parameter add an explicit parser, for example `parse(try_from_str)` = note: see also https://github.com/TeXitoi/structopt/tree/master/examples/true_or_false.rs --> $DIR/positional_bool.rs:5:14 | 5 | verbose: bool, | ^^^^ structopt-0.3.26/tests/ui/raw.rs000064400000000000000000000012640072674642500147340ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(StructOpt, Debug)] struct Opt { #[structopt(raw(case_insensitive = "true"))] s: String, } #[derive(StructOpt, Debug)] struct Opt2 { #[structopt(raw(requires_if = r#""one", "two""#))] s: String, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/raw.stderr000064400000000000000000000016600072674642500156130ustar 00000000000000error: `#[structopt(raw(...))` attributes are removed in structopt 0.3, they are replaced with raw methods = help: if you meant to call `clap::Arg::raw()` method you should use bool literal, like `raw(true)` or `raw(false)` = note: if you need to call `clap::Arg/App::case_insensitive` method you can do it like this: #[structopt(case_insensitive = true)] --> $DIR/raw.rs:13:17 | 13 | #[structopt(raw(case_insensitive = "true"))] | ^^^ error: `#[structopt(raw(...))` attributes are removed in structopt 0.3, they are replaced with raw methods = help: if you meant to call `clap::Arg::raw()` method you should use bool literal, like `raw(true)` or `raw(false)` = note: if you need to call `clap::Arg/App::requires_if` method you can do it like this: #[structopt(requires_if("one", "two"))] --> $DIR/raw.rs:19:17 | 19 | #[structopt(raw(requires_if = r#""one", "two""#))] | ^^^ structopt-0.3.26/tests/ui/rename_all_wrong_casing.rs000064400000000000000000000011330072674642500207750ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "basic", rename_all = "fail")] struct Opt { #[structopt(short)] s: String, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/rename_all_wrong_casing.stderr000064400000000000000000000002770072674642500216640ustar 00000000000000error: unsupported casing: `fail` --> $DIR/rename_all_wrong_casing.rs:12:42 | 12 | #[structopt(name = "basic", rename_all = "fail")] | ^^^^^^ structopt-0.3.26/tests/ui/skip_flatten.rs000064400000000000000000000017260072674642500166310ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "make-cookie")] struct MakeCookie { #[structopt(short)] s: String, #[structopt(skip, flatten)] cmd: Command, } #[derive(StructOpt, Debug)] enum Command { #[structopt(name = "pound")] /// Pound acorns into flour for cookie dough. Pound { acorns: u32 }, Sparkle { #[structopt(short)] color: String, }, } impl Default for Command { fn default() -> Self { Command::Pound { acorns: 0 } } } fn main() { let opt = MakeCookie::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/skip_flatten.stderr000064400000000000000000000002520072674642500175010ustar 00000000000000error: subcommand, flatten and skip cannot be used together --> $DIR/skip_flatten.rs:17:23 | 17 | #[structopt(skip, flatten)] | ^^^^^^^ structopt-0.3.26/tests/ui/skip_subcommand.rs000064400000000000000000000017310072674642500173200ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "make-cookie")] struct MakeCookie { #[structopt(short)] s: String, #[structopt(subcommand, skip)] cmd: Command, } #[derive(StructOpt, Debug)] enum Command { #[structopt(name = "pound")] /// Pound acorns into flour for cookie dough. Pound { acorns: u32 }, Sparkle { #[structopt(short)] color: String, }, } impl Default for Command { fn default() -> Self { Command::Pound { acorns: 0 } } } fn main() { let opt = MakeCookie::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/skip_subcommand.stderr000064400000000000000000000002630072674642500201760ustar 00000000000000error: subcommand, flatten and skip cannot be used together --> $DIR/skip_subcommand.rs:17:29 | 17 | #[structopt(subcommand, skip)] | ^^^^ structopt-0.3.26/tests/ui/skip_with_other_options.rs000064400000000000000000000003740072674642500211210ustar 00000000000000use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "test")] pub struct Opt { #[structopt(long)] a: u32, #[structopt(skip, long)] b: u32, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/skip_with_other_options.stderr000064400000000000000000000002320072674642500217710ustar 00000000000000error: methods are not allowed for skipped fields --> $DIR/skip_with_other_options.rs:8:17 | 8 | #[structopt(skip, long)] | ^^^^ structopt-0.3.26/tests/ui/skip_without_default.rs000064400000000000000000000012350072674642500203760ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(Debug)] enum Kind { A, B, } #[derive(StructOpt, Debug)] #[structopt(name = "test")] pub struct Opt { #[structopt(short)] number: u32, #[structopt(skip)] k: Kind, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/skip_without_default.stderr000064400000000000000000000004220072674642500212520ustar 00000000000000error[E0277]: the trait bound `Kind: Default` is not satisfied --> $DIR/skip_without_default.rs:22:17 | 22 | #[structopt(skip)] | ^^^^ the trait `Default` is not implemented for `Kind` | note: required by `std::default::Default::default` structopt-0.3.26/tests/ui/struct_parse.rs000064400000000000000000000011270072674642500166570ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "basic", parse(from_str))] struct Opt { #[structopt(short)] s: String, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/struct_parse.stderr000064400000000000000000000002630072674642500175360ustar 00000000000000error: `parse` attribute is only allowed on fields --> $DIR/struct_parse.rs:12:29 | 12 | #[structopt(name = "basic", parse(from_str))] | ^^^^^ structopt-0.3.26/tests/ui/struct_subcommand.rs000064400000000000000000000011220072674642500176700ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "basic", subcommand)] struct Opt { #[structopt(short)] s: String, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/struct_subcommand.stderr000064400000000000000000000002610072674642500205520ustar 00000000000000error: subcommand is only allowed on fields --> $DIR/struct_subcommand.rs:12:29 | 12 | #[structopt(name = "basic", subcommand)] | ^^^^^^^^^^ structopt-0.3.26/tests/ui/structopt_empty_attr.rs000064400000000000000000000011020072674642500204510ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "basic")] struct Opt { #[structopt] debug: bool, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/structopt_empty_attr.stderr000064400000000000000000000002370072674642500213400ustar 00000000000000error: expected attribute arguments in parentheses: #[structopt(...)] --> $DIR/structopt_empty_attr.rs:14:5 | 14 | #[structopt] | ^^^^^^^^^^^^ structopt-0.3.26/tests/ui/structopt_name_value_attr.rs000064400000000000000000000011140072674642500214320ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "basic")] struct Opt { #[structopt = "short"] debug: bool, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/structopt_name_value_attr.stderr000064400000000000000000000002310072674642500223100ustar 00000000000000error: expected parentheses: #[structopt(...)] --> $DIR/structopt_name_value_attr.rs:14:17 | 14 | #[structopt = "short"] | ^ structopt-0.3.26/tests/ui/subcommand_and_flatten.rs000064400000000000000000000015700072674642500206320ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "make-cookie")] struct MakeCookie { #[structopt(short)] s: String, #[structopt(subcommand, flatten)] cmd: Command, } #[derive(StructOpt, Debug)] enum Command { #[structopt(name = "pound")] /// Pound acorns into flour for cookie dough. Pound { acorns: u32 }, Sparkle { #[structopt(short)] color: String, }, } fn main() { let opt = MakeCookie::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/subcommand_and_flatten.stderr000064400000000000000000000003000072674642500214770ustar 00000000000000error: subcommand, flatten and skip cannot be used together --> $DIR/subcommand_and_flatten.rs:17:29 | 17 | #[structopt(subcommand, flatten)] | ^^^^^^^ structopt-0.3.26/tests/ui/subcommand_and_methods.rs000064400000000000000000000015650072674642500206440ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "make-cookie")] struct MakeCookie { #[structopt(short)] s: String, #[structopt(subcommand, long)] cmd: Command, } #[derive(StructOpt, Debug)] enum Command { #[structopt(name = "pound")] /// Pound acorns into flour for cookie dough. Pound { acorns: u32 }, Sparkle { #[structopt(short)] color: String, }, } fn main() { let opt = MakeCookie::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/subcommand_and_methods.stderr000064400000000000000000000002640072674642500215160ustar 00000000000000error: methods in attributes are not allowed for subcommand --> $DIR/subcommand_and_methods.rs:17:17 | 17 | #[structopt(subcommand, long)] | ^^^^^^^^^^ structopt-0.3.26/tests/ui/subcommand_and_parse.rs000064400000000000000000000016100072674642500203020ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "make-cookie")] struct MakeCookie { #[structopt(short)] s: String, #[structopt(subcommand, parse(from_occurrences))] cmd: Command, } #[derive(StructOpt, Debug)] enum Command { #[structopt(name = "pound")] /// Pound acorns into flour for cookie dough. Pound { acorns: u32 }, Sparkle { #[structopt(short)] color: String, }, } fn main() { let opt = MakeCookie::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/subcommand_and_parse.stderr000064400000000000000000000003050072674642500211610ustar 00000000000000error: parse attribute is not allowed for subcommand --> $DIR/subcommand_and_parse.rs:17:29 | 17 | #[structopt(subcommand, parse(from_occurrences))] | ^^^^^ structopt-0.3.26/tests/ui/subcommand_opt_opt.rs000064400000000000000000000015770072674642500200460ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "make-cookie")] struct MakeCookie { #[structopt(short)] s: String, #[structopt(subcommand)] cmd: Option>, } #[derive(StructOpt, Debug)] enum Command { #[structopt(name = "pound")] /// Pound acorns into flour for cookie dough. Pound { acorns: u32 }, Sparkle { #[structopt(short)] color: String, }, } fn main() { let opt = MakeCookie::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/subcommand_opt_opt.stderr000064400000000000000000000002650072674642500207160ustar 00000000000000error: Option> type is not allowed for subcommand --> $DIR/subcommand_opt_opt.rs:18:10 | 18 | cmd: Option>, | ^^^^^^^^^^^^^^^^^^^^^^^ structopt-0.3.26/tests/ui/subcommand_opt_vec.rs000064400000000000000000000015740072674642500200160ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "make-cookie")] struct MakeCookie { #[structopt(short)] s: String, #[structopt(subcommand)] cmd: Option>, } #[derive(StructOpt, Debug)] enum Command { #[structopt(name = "pound")] /// Pound acorns into flour for cookie dough. Pound { acorns: u32 }, Sparkle { #[structopt(short)] color: String, }, } fn main() { let opt = MakeCookie::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/subcommand_opt_vec.stderr000064400000000000000000000002540072674642500206670ustar 00000000000000error: Option> type is not allowed for subcommand --> $DIR/subcommand_opt_vec.rs:18:10 | 18 | cmd: Option>, | ^^^^^^^^^^^^^^^^^^^^ structopt-0.3.26/tests/ui/tuple_struct.rs000064400000000000000000000010410072674642500166710ustar 00000000000000// Copyright 2018 Guillaume Pinot (@TeXitoi) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "basic")] struct Opt(u32); fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.26/tests/ui/tuple_struct.stderr000064400000000000000000000004370072674642500175600ustar 00000000000000error: structopt only supports non-tuple structs and enums --> $DIR/tuple_struct.rs:11:10 | 11 | #[derive(StructOpt, Debug)] | ^^^^^^^^^ | = note: this error originates in the derive macro `StructOpt` (in Nightly builds, run with -Z macro-backtrace for more info) structopt-0.3.26/tests/utils.rs000064400000000000000000000023020072674642500146600ustar 00000000000000#![allow(unused)] use structopt::StructOpt; pub fn get_help() -> String { let mut output = Vec::new(); ::clap().write_help(&mut output).unwrap(); let output = String::from_utf8(output).unwrap(); eprintln!("\n%%% HELP %%%:=====\n{}\n=====\n", output); eprintln!("\n%%% HELP (DEBUG) %%%:=====\n{:?}\n=====\n", output); output } pub fn get_long_help() -> String { let mut output = Vec::new(); ::clap() .write_long_help(&mut output) .unwrap(); let output = String::from_utf8(output).unwrap(); eprintln!("\n%%% LONG_HELP %%%:=====\n{}\n=====\n", output); eprintln!("\n%%% LONG_HELP (DEBUG) %%%:=====\n{:?}\n=====\n", output); output } pub fn get_subcommand_long_help(subcmd: &str) -> String { let output = ::clap() .get_matches_from_safe(vec!["test", subcmd, "--help"]) .expect_err("") .message; eprintln!( "\n%%% SUBCOMMAND `{}` HELP %%%:=====\n{}\n=====\n", subcmd, output ); eprintln!( "\n%%% SUBCOMMAND `{}` HELP (DEBUG) %%%:=====\n{:?}\n=====\n", subcmd, output ); output } structopt-0.3.26/tests/we_need_syn_full.rs000064400000000000000000000006750072674642500170540ustar 00000000000000// See https://github.com/TeXitoi/structopt/issues/354 use structopt::StructOpt; #[test] fn we_need_syn_full() { #[allow(unused)] #[derive(Debug, StructOpt, Clone)] struct Args { #[structopt( short = "c", long = "colour", help = "Output colouring", default_value = "auto", possible_values = &["always", "auto", "never"] )] colour: String, } }