structopt-0.3.1/.gitignore010064400017500001750000000000461350211501100137600ustar0000000000000000target Cargo.lock *~ .idea/ .vscode/ structopt-0.3.1/.travis.yml010064400017500001750000000004441353221554000141160ustar0000000000000000language: rust cache: cargo matrix: include: - rust: 1.36.0 - rust: stable - rust: beta - rust: nightly - rust: stable env: RUN=FMT before_script: rustup component add rustfmt-preview script: cargo fmt --all -- --check script: - cargo test $FEATURES structopt-0.3.1/CHANGELOG.md010064400017500001750000000324361353440517300136310ustar0000000000000000# 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.1/Cargo.toml.orig010064400017500001750000000017071353440504500147020ustar0000000000000000[package] name = "structopt" version = "0.3.1" 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/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"] [badges] travis-ci = { repository = "TeXitoi/structopt" } [dependencies] clap = { version = "2.33", default-features = false } structopt-derive = { path = "structopt-derive", version = "0.3.1" } [dev-dependencies] trybuild = "1.0.5" version_check = "0.9" [workspace] structopt-0.3.1/Cargo.toml0000644000000027120000000000000111430ustar00# 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 believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] edition = "2018" name = "structopt" version = "0.3.1" 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/MIT" repository = "https://github.com/TeXitoi/structopt" [dependencies.clap] version = "2.33" default-features = false [dependencies.structopt-derive] version = "0.3.1" [dev-dependencies.trybuild] version = "1.0.5" [dev-dependencies.version_check] version = "0.9" [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"] suggestions = ["clap/suggestions"] wrap_help = ["clap/wrap_help"] yaml = ["clap/yaml"] [badges.travis-ci] repository = "TeXitoi/structopt" structopt-0.3.1/LICENSE-APACHE010064400017500001750000000261351350211501100137230ustar0000000000000000 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.1/LICENSE-MIT010064400017500001750000000021201350211501100134170ustar0000000000000000MIT 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.1/README.md010064400017500001750000000104401353440500700132620ustar0000000000000000# StructOpt [![Build status](https://travis-ci.org/TeXitoi/structopt.svg?branch=master)](https://travis-ci.org/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) Parse command line arguments by defining a struct. It combines [clap](https://crates.io/crates/clap) with custom derive. ## 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.1/examples/at_least_two.rs010064400017500001750000000003311352446560400166620ustar0000000000000000use 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.1/examples/basic.rs010064400017500001750000000030651352446560400152650ustar0000000000000000// 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 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.1/examples/deny_missing_docs.rs010064400017500001750000000022611352446560400177010ustar0000000000000000// 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) #![deny(missing_docs)] use structopt::StructOpt; /// The options #[derive(StructOpt, Debug, PartialEq)] pub struct Opt { #[structopt(short = "v")] verbose: bool, #[structopt(subcommand)] cmd: Option, } /// Some subcommands #[derive(StructOpt, Debug, PartialEq)] pub enum Cmd { /// command A A, /// command B B { /// Alice? #[structopt(short = "a")] alice: bool, }, /// command C C(COpt), } /// The options for C #[derive(StructOpt, Debug, PartialEq)] pub struct COpt { #[structopt(short = "b")] bob: bool, } fn main() { println!("{:?}", Opt::from_args()); } structopt-0.3.1/examples/doc_comments.rs010064400017500001750000000051511352446560400166540ustar0000000000000000// 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; /// 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 = "f", long = "first-flag")] 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 = "s", long = "second-flag")] second_flag: bool, #[structopt( short = "t", long = "third-flag", 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. #[structopt(name = "first")] 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. #[structopt(name = "second")] Second, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.1/examples/enum_in_args.rs010064400017500001750000000007511352446560400166510ustar0000000000000000//! current `clap::arg_enum!` uses "non-ident macro path" feature, which was stabilized in //! Rust 1.31.0. 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.1/examples/enum_tuple.rs010064400017500001750000000006711352446560400163610ustar0000000000000000use 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.1/examples/env.rs010064400017500001750000000012431352446560400147700ustar0000000000000000use 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.1/examples/example.rs010064400017500001750000000041461352446560400156400ustar0000000000000000// 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 = "example", about = "An example of StructOpt usage.")] struct Opt { /// A flag, true if used in the command line. #[structopt(short = "d", long = "debug", help = "Activate debug mode")] debug: bool, /// An argument of type float, with a default value. #[structopt(short = "s", long = "speed", help = "Set speed", default_value = "42")] speed: f64, /// Needed parameter, the first on the command line. #[structopt(help = "Input file")] input: String, /// An optional parameter, will be `None` if not present on the /// command line. #[structopt(help = "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 = "log", help = "Log file, stdout if no file, no logging if not present" )] #[allow(clippy::option_option)] 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(Some(String))` if /// argument list is provided (e.g. `--optv a b c`). #[structopt(long = "optv")] optv: Option>, /// Skipped option: it won't be parsed and will be filled with the /// default value for its type (in this case ''). #[structopt(skip)] skipped: String, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.1/examples/flatten.rs010064400017500001750000000007371352446560400156440ustar0000000000000000use structopt::StructOpt; #[derive(StructOpt, Debug)] struct Cmdline { #[structopt(short = "v", help = "switch on verbosity")] verbose: bool, #[structopt(flatten)] daemon_opts: DaemonOpts, } #[derive(StructOpt, Debug)] struct DaemonOpts { #[structopt(short = "u", help = "daemon user")] user: String, #[structopt(short = "g", help = "daemon group")] group: String, } fn main() { let opt = Cmdline::from_args(); println!("{:?}", opt); } structopt-0.3.1/examples/gen_completions.rs010064400017500001750000000015551352446560400173730ustar0000000000000000// 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. use structopt::clap::Shell; use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "example", about = "An example of StructOpt usage.")] struct Opt { /// A flag, true if used in the command line. #[structopt(short = "d", long = "debug", help = "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.1/examples/git.rs010064400017500001750000000016711352446560400147700ustar0000000000000000//! `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 the //! `about` attribute. use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "git")] /// the stupid content tracker enum Opt { #[structopt(name = "fetch")] /// fetch branches from remote repository Fetch { #[structopt(long = "dry-run")] dry_run: bool, #[structopt(long = "all")] all: bool, #[structopt(default_value = "origin")] repository: String, }, #[structopt(name = "add")] /// add files to the staging area Add { #[structopt(short = "i")] interactive: bool, #[structopt(short = "a")] all: bool, files: Vec, }, } fn main() { let matches = Opt::from_args(); println!("{:?}", matches); } structopt-0.3.1/examples/group.rs010064400017500001750000000021501352446560400153320ustar0000000000000000// A functional translation of the example at // https://docs.rs/clap/2.31.2/clap/struct.App.html#method.group use structopt::clap::ArgGroup; use structopt::StructOpt; // This function is not needed, we can insert everything in the group // attribute, but, as it might be long, using a function is more // lisible. fn vers_arg_group() -> ArgGroup<'static> { // As the attributes of the struct are executed before the struct // fields, we can't use .args(...), but we can use the group // attribute on the fields. ArgGroup::with_name("vers").required(true) } #[derive(StructOpt, Debug)] #[structopt(group = vers_arg_group())] struct Opt { /// set the version manually #[structopt(long = "set-ver", group = "vers")] set_ver: Option, /// auto increase major #[structopt(long = "major", group = "vers")] major: bool, /// auto increase minor #[structopt(long = "minor", group = "vers")] minor: bool, /// auto increase patch #[structopt(long = "patch", group = "vers")] patch: bool, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.1/examples/keyvalue.rs010064400017500001750000000017721353173232200160240ustar0000000000000000use 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.1/examples/no_version.rs010064400017500001750000000004371353173232200163550ustar0000000000000000use 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.1/examples/rename_all.rs010064400017500001750000000050611352446560400163010ustar0000000000000000//! 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. 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.1/examples/simple_group.rs010064400017500001750000000013021352446560400167010ustar0000000000000000use structopt::StructOpt; #[derive(StructOpt, Debug)] struct Opt { /// Set a custom HTTP verb #[structopt(long = "method", group = "verb")] method: Option, /// HTTP GET; default if no other HTTP verb is selected #[structopt(long = "get", group = "verb")] get: bool, /// HTTP HEAD #[structopt(long = "head", group = "verb")] head: bool, /// HTTP POST #[structopt(long = "post", group = "verb")] post: bool, /// HTTP PUT #[structopt(long = "put", group = "verb")] put: bool, /// HTTP DELETE #[structopt(long = "delete", group = "verb")] delete: bool, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.1/examples/skip.rs010064400017500001750000000010731353221400700151330ustar0000000000000000use structopt::StructOpt; #[derive(StructOpt, Debug, PartialEq)] #[structopt(name = "a")] pub struct Opt { #[structopt(long, short)] number: u32, #[structopt(skip)] k: Kind, #[structopt(skip)] v: Vec, } #[derive(Debug, PartialEq)] #[allow(unused)] 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![], } ); } structopt-0.3.1/examples/subcommand_aliases.rs010064400017500001750000000010641352446560400200320ustar0000000000000000use 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(name = "foo", alias = "foobar")] Foo, // https://docs.rs/clap/2/clap/struct.App.html#method.aliases #[structopt(name = "bar", aliases = &["baz", "fizz"])] Bar, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.1/src/lib.rs010064400017500001750000000621041353440500700137120ustar0000000000000000// 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)] //! This crate defines the `StructOpt` trait and its custom derive. //! //! ## 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.2", 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.2", features = [ "paw" ] } //! paw = "1.0" //! ``` //! //! ## How to `derive(StructOpt)` //! //! First, let's look at the example: //! //! ```should_panic //! 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` is set to `file` //! #[structopt(name = "FILE", required_if("out_type", "file"))] //! file_name: String, //! } //! //! fn main() { //! let opt = Opt::from_args(); //! 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). //! //! ## Attributes //! //! `#[structopt(...)]` 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: //! ```rust,ignore //! #[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 //! )] //! ``` //! //! `#[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("s") //! .long("speed") //! .default_value("42")) //! // and so on //! # ; //! ``` //! //! ## Raw methods //! //! They are the reason why `structopt` is so flexible. //! //! Each and every method from `clap::App` and `clap::Arg` can be used directly - //! just `#[structopt(method_name = single_arg)]` or `#[structopt(method_name(arg1, arg2))]` //! and it just works. As long as `method_name` is not one of the magical methods - //! it's just a method call. //! //! **Note:** the `Arg::raw` method is allowed only with `true` or `false` literals. //! //! ## 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 = "name"]` //! - On top level: `App::new("name")`. //! //! The binary name displayed in help messages. Defaults to the crate name given by Cargo. //! //! - On field-level: `Arg::with_name("name")`. //! //! 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_AUTHOR))`. //! //! 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. //! //! - [`rename_all`](#specifying-argument-types): [`rename_all = "kebab"/"snake"/"screaming-snake"/"camel"/"pascal"/"verbatim"]` //! //! Usable only on top level //! //! - [`parse`](#custom-string-parsers): `parse(type [= path::to::parser::fn])` //! //! Usable only on field-level. //! //! - [`skip`](#skipping-fields): `skip` //! //! Usable only on field-level. //! //! - [`flatten`](#flattening): `flatten` //! //! Usable only on field-level. //! //! - [`subcommand`](#subcommands): `subcommand` //! //! Usable only on field-level. //! //! ## Type magic //! //! One of major things that makes `structopt` so awesome is it's 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. //! //! Thus, the `speed` argument is generated as: //! //! ``` //! # extern crate clap; //! # fn parse_validator(_: String) -> Result<(), String> { unimplemented!() } //! # fn main() { //! clap::Arg::with_name("speed") //! .takes_value(true) //! .multiple(false) //! .required(false) //! .validator(parse_validator::) //! .short("s") //! .long("speed") //! .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, //! //! } //! //! # fn main() { //! # Opt::from_clap(&Opt::clap().get_matches_from( //! # &["test", "--foo-option", "", "-b", "", "--baz", "", "--custom", "", "positional"])); //! # } //! ``` //! //! ## Help messages //! //! Help messages for the whole binary or individual arguments can be //! specified using the `about` attribute on the struct and the `help` //! attribute on the field, as we've already seen. For convenience, //! they can also be specified using doc comments. For example: //! //! ``` //! # use structopt::StructOpt; //! //! #[derive(StructOpt)] //! /// The help message that will be displayed when passing `--help`. //! struct Foo { //! #[structopt(short)] //! /// The description for the arg that will be displayed when passing `--help`. //! bar: String //! } //! # fn main() {} //! ``` //! //! If it is necessary or wanted to provide a more complex help message then the //! previous used ones, it could still be a good idea to distinguish between the //! actual help message a short summary. In this case `about` and `help` should //! only contain the short and concise form while the two additional arguments //! `long_about` and `long_help` can be used to store a descriptive and more in //! depth message. //! //! If both - the short and the long version of the argument - are present, //! the user can later chose between the short summary (`-h`) and the long //! descriptive version (`--help`) of the help message. Also in case //! of subcommands the short help message will automatically be used for the //! command description inside the parents help message and the long version //! as command description if help is requested on the actual subcommand. //! //! This feature can also be used with doc comments instead of arguments through //! proper comment formatting. To be activated it requires, that the first line //! of the comment is separated from the rest of the comment through an empty line. //! In this case the first line is used as summary and the whole comment represents //! the long descriptive message. //! //! ``` //! # use structopt::StructOpt; //! //! #[derive(StructOpt)] //! /// The help message that will be displayed when passing `--help`. //! struct Foo { //! #[structopt(short)] //! /// Only this summary is visible when passing `-h`. //! /// //! /// But the whole comment will be displayed when passing `--help`. //! /// This could be quite useful to provide further hints are usage //! /// examples. //! bar: String //! } //! # fn main() {} //! ``` //! //! ## 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")] //! param: String //! } //! # fn main() {} //! ``` //! //! By default, values from the environment are shown in the help output (i.e. when invoking //! `--help`): //! //! ```shell //! $ cargo run -- --help //! ... //! OPTIONS: //! -p, --param [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 strucopt emit the actual secret values: //! ``` //! # use structopt::StructOpt; //! //! #[derive(StructOpt)] //! struct Foo { //! #[structopt(long = "secret", env = "SECRET_VALUE", hide_env_values = true)] //! param: String //! } //! # fn main() {} //! ``` //! //! ## 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)]`. Note that //! the field type has to implement `std::default::Default` then. //! //! ## 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 //! } //! } //! # fn main() {} //! ``` //! //! 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; //! # fn main() {} //! #[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 //! //! A nested subcommand can be marked optional: //! //! ``` //! # use structopt::StructOpt; //! # fn main() {} //! #[derive(StructOpt)] //! struct Foo { //! file: String, //! #[structopt(subcommand)] //! cmd: Option //! } //! //! #[derive(StructOpt)] //! enum Command { //! Bar, //! Baz, //! Quux //! } //! ``` //! //! ## 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; //! # fn main() {} //! #[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; //! # fn main() {} //! 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` | //! //! 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.). //! //! 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. #[doc(hidden)] pub use structopt_derive::*; use std::ffi::OsString; /// Re-export of clap pub use clap; /// A struct that is converted from command line arguments. pub trait StructOpt { /// Returns the corresponding `clap::App`. fn clap<'a, 'b>() -> clap::App<'a, 'b>; /// Creates the struct from `clap::ArgMatches`. It cannot fail /// with a parameter generated by `clap` by construction. fn from_clap(matches: &clap::ArgMatches<'_>) -> Self; /// Gets the struct from the command line arguments. Print the /// error message and quit the program in case of failure. fn from_args() -> Self where Self: Sized, { Self::from_clap(&Self::clap().get_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. 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()` you must call `.exit()` on the error value. 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)?)) } } structopt-0.3.1/tests/argument_naming.rs010064400017500001750000000166441352446560400167120ustar0000000000000000use 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"])) ); } structopt-0.3.1/tests/arguments.rs010064400017500001750000000046041352446560400155350ustar0000000000000000// 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.1/tests/author_version_about.rs010064400017500001750000000022671353173232200177640ustar0000000000000000// 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 no_author_version_about() { #[derive(StructOpt, PartialEq, Debug)] #[structopt(name = "foo", no_version)] struct Opt {} let mut output = Vec::new(); Opt::clap().write_long_help(&mut output).unwrap(); let output = String::from_utf8(output).unwrap(); assert!(output.starts_with("foo \n\nUSAGE:")); } #[test] fn use_env() { #[derive(StructOpt, PartialEq, Debug)] #[structopt(author, about)] struct Opt {} let mut output = Vec::new(); Opt::clap().write_long_help(&mut output).unwrap(); let output = String::from_utf8(output).unwrap(); assert!(output.starts_with("structopt 0.")); assert!(output.contains("Guillaume Pinot , others")); assert!(output.contains("Parse command line argument by defining a struct.")); } structopt-0.3.1/tests/custom-string-parsers.rs010064400017500001750000000171501352446560400200230ustar0000000000000000// 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::{OsStr, OsString}; use std::num::ParseIntError; use std::path::PathBuf; #[derive(StructOpt, PartialEq, Debug)] struct PathOpt { #[structopt(short = "p", long = "path", parse(from_os_str))] path: PathBuf, #[structopt(short = "d", default_value = "../", parse(from_os_str))] default_path: PathBuf, #[structopt(short = "v", parse(from_os_str))] vector_path: Vec, #[structopt(short = "o", 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 = "n", 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 = "a", parse(from_str = custom_parser_1))] a: &'static str, #[structopt(short = "b", parse(try_from_str = custom_parser_2))] b: &'static str, #[structopt(short = "c", parse(from_os_str = custom_parser_3))] c: &'static str, #[structopt(short = "d", 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 = "b", parse(from_str))] bytes: Bytes, #[structopt(short = "i", parse(try_from_str))] integer: u64, #[structopt(short = "p", 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 = "s", long = "signed", parse(from_occurrences))] signed: i32, #[structopt(short = "l", parse(from_occurrences))] little_signed: i8, #[structopt(short = "u", parse(from_occurrences))] unsigned: usize, #[structopt(short = "r", parse(from_occurrences))] little_unsigned: u8, #[structopt(short = "c", long = "custom", 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 = "d", parse(try_from_str = parse_bool))] debug: bool, #[structopt( short = "v", default_value = "false", parse(try_from_str = parse_bool) )] verbose: bool, #[structopt(short = "t", parse(try_from_str = parse_bool))] tribool: Option, #[structopt(short = "b", 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"]) ); } structopt-0.3.1/tests/deny-warnings.rs010064400017500001750000000022731352446560400163150ustar0000000000000000// 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)] #![cfg(feature = "nightly")] // TODO: remove that when never is stable #![feature(never_type)] 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.1/tests/doc-comments-help.rs010064400017500001750000000101141353173232200170270ustar0000000000000000// 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 commets_intead_of_actual_help() { /// Lorem ipsum #[derive(StructOpt, PartialEq, Debug)] struct LoremIpsum { /// Fooify a bar /// and a baz #[structopt(short = "f", long = "foo")] foo: bool, } let mut output = Vec::new(); LoremIpsum::clap().write_long_help(&mut output).unwrap(); let output = String::from_utf8(output).unwrap(); assert!(output.contains("Lorem ipsum")); assert!(output.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 = "f", long = "foo", help = "DO NOT PASS A BAR UNDER ANY CIRCUMSTANCES" )] foo: bool, } let mut output = Vec::new(); LoremIpsum::clap().write_long_help(&mut output).unwrap(); let output = String::from_utf8(output).unwrap(); assert!(output.contains("Dolor sit amet")); assert!(!output.contains("Lorem ipsum")); assert!(output.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 mut output = Vec::new(); LoremIpsum::clap().write_long_help(&mut output).unwrap(); let output = String::from_utf8(output).unwrap(); println!("{}", output); assert!(output.starts_with("lorem-ipsum \nFoo.\n\nBar\n\nUSAGE:")); } #[test] fn splits_flag_doc_comment_between_short_and_long() { /// Lorem ipsumclap #[derive(StructOpt, PartialEq, Debug)] #[structopt(name = "lorem-ipsum", about = "Dolor sit amet")] struct LoremIpsum { /// DO NOT PASS A BAR UNDER ANY CIRCUMSTANCES. /// /// Or something else #[structopt(long = "foo")] foo: bool, } let mut app = LoremIpsum::clap(); let short_help = { let mut buffer = Vec::new(); app.write_help(&mut buffer).ok(); String::from_utf8(buffer).unwrap() }; let long_help = { let mut buffer = Vec::new(); app.write_long_help(&mut buffer).ok(); String::from_utf8(buffer).unwrap() }; assert!(short_help.contains("CIRCUMSTANCES")); assert!(!short_help.contains("CIRCUMSTANCES.")); 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 splits_subcommand_doc_comment_between_short_and_long() { /// 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 #[structopt(name = "foo")] Foo { #[structopt(help = "foo")] bars: Vec, }, } let app = LoremIpsum::clap(); let short_help = { let mut buffer = Vec::new(); app.write_help(&mut buffer).ok(); String::from_utf8(buffer).unwrap() }; let long_help = { app.get_matches_from_safe(vec!["test", "foo", "--help"]) .expect_err("") .message }; 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")); } structopt-0.3.1/tests/flags.rs010064400017500001750000000071611352446560400146250ustar0000000000000000// 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 = "a", long = "alice")] 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 = "a", long = "alice", parse(from_occurrences))] alice: u64, #[structopt(short = "b", long = "bob", 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()); } #[test] fn combined_flags() { #[derive(StructOpt, PartialEq, Debug)] struct Opt { #[structopt(short = "a", long = "alice")] alice: bool, #[structopt(short = "b", long = "bob", 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.1/tests/flatten.rs010064400017500001750000000043611352446560400151650ustar0000000000000000// 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 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 = "i")] interactive: bool, #[structopt(flatten)] common: Common, } #[derive(StructOpt, PartialEq, Debug)] enum Opt { #[structopt(name = "fetch")] Fetch { #[structopt(short = "a")] all: bool, #[structopt(flatten)] common: Common, }, #[structopt(name = "add")] 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"]) ); } structopt-0.3.1/tests/macro-errors.rs010064400017500001750000000012711353221400700161240ustar0000000000000000// 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 extern crate version_check; use version_check::Version; #[test] fn ui() { let t = trybuild::TestCases::new(); t.compile_fail("tests/ui-common/*.rs"); let version = Version::read().unwrap(); if version.at_least("1.39.0") { t.compile_fail("tests/ui-1.39_post/*.rs"); } else { t.compile_fail("tests/ui-pre_1.39/*.rs"); } } structopt-0.3.1/tests/nested-subcommands.rs010064400017500001750000000116151352446560400173230ustar0000000000000000// 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 = "f", long = "force")] force: bool, #[structopt(short = "v", long = "verbose", parse(from_occurrences))] verbose: u64, #[structopt(subcommand)] cmd: Sub, } #[derive(StructOpt, PartialEq, Debug)] enum Sub { #[structopt(name = "fetch")] Fetch {}, #[structopt(name = "add")] Add {}, } #[derive(StructOpt, PartialEq, Debug)] struct Opt2 { #[structopt(short = "f", long = "force")] force: bool, #[structopt(short = "v", long = "verbose", 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 = "a", long = "all")] all: bool, #[structopt(subcommand)] cmd: Sub2, } #[derive(StructOpt, PartialEq, Debug)] enum Sub2 { #[structopt(name = "foo")] Foo { file: String, #[structopt(subcommand)] cmd: Sub3, }, #[structopt(name = "bar")] Bar {}, } #[derive(StructOpt, PartialEq, Debug)] enum Sub3 { #[structopt(name = "baz")] Baz {}, #[structopt(name = "quux")] 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 { #[structopt(name = "remote")] Remote { #[structopt(subcommand)] cmd: Option, }, #[structopt(name = "stash")] Stash { #[structopt(subcommand)] cmd: Stash, }, } #[derive(StructOpt, PartialEq, Debug)] enum Remote { #[structopt(name = "add")] Add { name: String, url: String }, #[structopt(name = "remove")] Remove { name: String }, } #[derive(StructOpt, PartialEq, Debug)] enum Stash { #[structopt(name = "save")] Save, #[structopt(name = "pop")] 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.1/tests/non_literal_attributes.rs010064400017500001750000000075471352446560400203150ustar0000000000000000// 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.1/tests/options.rs010064400017500001750000000206231352446560400152220ustar0000000000000000// 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 = "a", long = "arg")] 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 = "a")] 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 = "a", 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 = "a", 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 = "a", long = "arg")] 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 = "a", 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 = "a")] #[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 = "a")] arg: Option>, #[structopt(long = "field")] 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 = "a")] 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 = "a")] arg: Option>, #[structopt(short = "b")] 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.1/tests/privacy.rs010064400017500001750000000015211352446560400152000ustar0000000000000000// 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 { #[structopt(name = "foo", about = "foo")] Foo { #[structopt(help = "foo")] bars: Vec, }, } } structopt-0.3.1/tests/raw_bool_literal.rs010064400017500001750000000014561353173232200170420ustar0000000000000000// 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.1/tests/skip.rs010064400017500001750000000051071353440500700144650ustar0000000000000000// 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)] #[structopt(name = "a")] 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)] #[structopt(name = "a")] 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, } ); } structopt-0.3.1/tests/subcommands.rs010064400017500001750000000127451352446560400160500ustar0000000000000000// 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)] enum Opt { #[structopt(name = "fetch", about = "Fetch stuff from GitHub.")] Fetch { #[structopt(long = "all")] all: bool, #[structopt(short = "f", long = "force")] /// Overwrite local branches. force: bool, repo: String, }, #[structopt(name = "add")] Add { #[structopt(short = "i", long = "interactive")] interactive: bool, #[structopt(short = "v", long = "verbose")] 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 { #[structopt(name = "do-something")] 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 { #[structopt(name = "add")] Add, #[structopt(name = "init")] Init, #[structopt(name = "fetch")] 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 #[structopt(name = "add", about = "Add a file")] Add(Add), #[structopt(name = "init")] Init, /// download history from remote #[structopt(name = "fetch")] 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 mut output = Vec::new(); Opt4::clap().write_long_help(&mut output).unwrap(); let output = String::from_utf8(output).unwrap(); 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 { #[structopt(name = "daemon")] Daemon(DaemonCommand), } #[derive(StructOpt, Debug, PartialEq)] pub enum DaemonCommand { #[structopt(name = "start")] Start, #[structopt(name = "stop")] 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 } ); } structopt-0.3.1/tests/ui-1.39_post/opt_opt_nonpositional.rs010064400017500001750000000010731353440500700222270ustar0000000000000000// 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.1/tests/ui-1.39_post/opt_opt_nonpositional.stderr010064400017500001750000000002641353221400700231030ustar0000000000000000error: Option> type is meaningless for positional argument --> $DIR/opt_opt_nonpositional.rs:14:8 | 14 | n: Option>, | ^^^^^^^^^^^^^^^^^^^ structopt-0.3.1/tests/ui-1.39_post/opt_vec_nonpositional.rs010064400017500001750000000010701353440500700221770ustar0000000000000000// 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.1/tests/ui-1.39_post/opt_vec_nonpositional.stderr010064400017500001750000000002531353221400700230540ustar0000000000000000error: Option> type is meaningless for positional argument --> $DIR/opt_vec_nonpositional.rs:14:8 | 14 | n: Option>, | ^^^^^^^^^^^^^^^^ structopt-0.3.1/tests/ui-1.39_post/subcommand_opt_opt.rs010064400017500001750000000015771353440500700214740ustar0000000000000000// 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.1/tests/ui-1.39_post/subcommand_opt_opt.stderr010064400017500001750000000002651353221400700223400ustar0000000000000000error: Option> type is not allowed for subcommand --> $DIR/subcommand_opt_opt.rs:18:10 | 18 | cmd: Option>, | ^^^^^^^^^^^^^^^^^^^^^^^ structopt-0.3.1/tests/ui-1.39_post/subcommand_opt_vec.rs010064400017500001750000000015741353440500700214440ustar0000000000000000// 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.1/tests/ui-1.39_post/subcommand_opt_vec.stderr010064400017500001750000000002541353221400700223110ustar0000000000000000error: Option> type is not allowed for subcommand --> $DIR/subcommand_opt_vec.rs:18:10 | 18 | cmd: Option>, | ^^^^^^^^^^^^^^^^^^^^ structopt-0.3.1/tests/ui-common/bool_default_value.rs010064400017500001750000000011321353440500700212470ustar0000000000000000// 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.1/tests/ui-common/bool_default_value.stderr010064400017500001750000000002661353221400700221310ustar0000000000000000error: default_value is meaningless for bool --> $DIR/bool_default_value.rs:14:24 | 14 | #[structopt(short, default_value = true)] | ^^^^^^^^^^^^^ structopt-0.3.1/tests/ui-common/bool_required.rs010064400017500001750000000011251353440500700202510ustar0000000000000000// 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.1/tests/ui-common/bool_required.stderr010064400017500001750000000002421353221400700211230ustar0000000000000000error: required is meaningless for bool --> $DIR/bool_required.rs:14:24 | 14 | #[structopt(short, required = true)] | ^^^^^^^^ structopt-0.3.1/tests/ui-common/flatten_and_doc.rs010064400017500001750000000013451353440500700205260ustar0000000000000000// 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 { /// Opts. #[structopt(flatten)] opts: DaemonOpts, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.1/tests/ui-common/flatten_and_doc.stderr010064400017500001750000000002511353221400700213740ustar0000000000000000error: methods and doc comments are not allowed for flattened entry --> $DIR/flatten_and_doc.rs:23:17 | 23 | #[structopt(flatten)] | ^^^^^^^ structopt-0.3.1/tests/ui-common/flatten_and_methods.rs010064400017500001750000000013361353440500700214240ustar0000000000000000// 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.1/tests/ui-common/flatten_and_methods.stderr010064400017500001750000000002731353221400700222760ustar0000000000000000error: methods and doc comments are not allowed for flattened entry --> $DIR/flatten_and_methods.rs:22:24 | 22 | #[structopt(short, flatten)] | ^^^^^^^ structopt-0.3.1/tests/ui-common/flatten_and_parse.rs010064400017500001750000000013601353440500700210700ustar0000000000000000// 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.1/tests/ui-common/flatten_and_parse.stderr010064400017500001750000000003011353221400700217350ustar0000000000000000error: parse attribute is not allowed for flattened entry --> $DIR/flatten_and_parse.rs:22:26 | 22 | #[structopt(flatten, parse(from_occurrences))] | ^^^^^ structopt-0.3.1/tests/ui-common/non_existent_attr.rs010064400017500001750000000011441353440500700211660ustar0000000000000000// 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.1/tests/ui-common/non_existent_attr.stderr010064400017500001750000000005261353221400700220440ustar0000000000000000error[E0599]: no method named `non_existing_attribute` found for type `clap::args::arg::Arg<'_, '_>` in the current scope --> $DIR/non_existent_attr.rs:14:24 | 14 | #[structopt(short, non_existing_attribute = 1)] | ^^^^^^^^^^^^^^^^^^^^^^ For more information about this error, try `rustc --explain E0599`. structopt-0.3.1/tests/ui-common/option_default_value.rs010064400017500001750000000011361353440500700216300ustar0000000000000000// 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.1/tests/ui-common/option_default_value.stderr010064400017500001750000000002671353221400700225070ustar0000000000000000error: default_value is meaningless for Option --> $DIR/option_default_value.rs:14:24 | 14 | #[structopt(short, default_value = 1)] | ^^^^^^^^^^^^^ structopt-0.3.1/tests/ui-common/option_required.rs010064400017500001750000000011341353440500700206260ustar0000000000000000// 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.1/tests/ui-common/option_required.stderr010064400017500001750000000002461353221400700215040ustar0000000000000000error: required is meaningless for Option --> $DIR/option_required.rs:14:24 | 14 | #[structopt(short, required = true)] | ^^^^^^^^ structopt-0.3.1/tests/ui-common/parse_empty_try_from_os.rs010064400017500001750000000011271353440500700223720ustar0000000000000000// 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.1/tests/ui-common/parse_empty_try_from_os.stderr010064400017500001750000000003111353221400700232370ustar0000000000000000error: cannot omit parser function name with `try_from_os_str` --> $DIR/parse_empty_try_from_os.rs:14:23 | 14 | #[structopt(parse(try_from_os_str))] | ^^^^^^^^^^^^^^^ structopt-0.3.1/tests/ui-common/parse_function_is_not_path.rs010064400017500001750000000011261353440500700230250ustar0000000000000000// 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.1/tests/ui-common/parse_function_is_not_path.stderr010064400017500001750000000002731353221400700237020ustar0000000000000000error: `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.1/tests/ui-common/parse_literal_spec.rs010064400017500001750000000011221353440500700212530ustar0000000000000000// 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.1/tests/ui-common/parse_literal_spec.stderr010064400017500001750000000002621353221400700221320ustar0000000000000000error: parser specification must start with identifier --> $DIR/parse_literal_spec.rs:14:23 | 14 | #[structopt(parse("from_str"))] | ^^^^^^^^^^ structopt-0.3.1/tests/ui-common/parse_not_zero_args.rs010064400017500001750000000011321353440500700214610ustar0000000000000000// 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.1/tests/ui-common/parse_not_zero_args.stderr010064400017500001750000000002451353221400700223400ustar0000000000000000error: parse must have exactly one argument --> $DIR/parse_not_zero_args.rs:14:17 | 14 | #[structopt(parse(from_str, from_str))] | ^^^^^ structopt-0.3.1/tests/ui-common/raw.rs010064400017500001750000000011021353440500700162020ustar0000000000000000// 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, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.1/tests/ui-common/raw.stderr010064400017500001750000000003451353440500700170710ustar0000000000000000error: `#[structopt(raw(...))` attributes are deprecated in structopt 0.3, only `raw(true)` and `raw(false)` are allowed --> $DIR/raw.rs:13:17 | 13 | #[structopt(raw(case_insensitive = "true"))] | ^^^ structopt-0.3.1/tests/ui-common/rename_all_wrong_casing.rs010064400017500001750000000011331353440500700222540ustar0000000000000000// 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.1/tests/ui-common/rename_all_wrong_casing.stderr010064400017500001750000000002771353221400700231370ustar0000000000000000error: unsupported casing: `fail` --> $DIR/rename_all_wrong_casing.rs:12:42 | 12 | #[structopt(name = "basic", rename_all = "fail")] | ^^^^^^ structopt-0.3.1/tests/ui-common/skip_flatten.rs010064400017500001750000000017261353440500700201100ustar0000000000000000// 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.1/tests/ui-common/skip_flatten.stderr010064400017500001750000000002521353221400700207540ustar0000000000000000error: subcommand, flatten and skip cannot be used together --> $DIR/skip_flatten.rs:17:23 | 17 | #[structopt(skip, flatten)] | ^^^^^^^ structopt-0.3.1/tests/ui-common/skip_subcommand.rs010064400017500001750000000017311353440500700205770ustar0000000000000000// 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.1/tests/ui-common/skip_subcommand.stderr010064400017500001750000000002631353221400700214510ustar0000000000000000error: subcommand, flatten and skip cannot be used together --> $DIR/skip_subcommand.rs:17:29 | 17 | #[structopt(subcommand, skip)] | ^^^^ structopt-0.3.1/tests/ui-common/skip_with_other_options.rs010064400017500001750000000003741353440500700224000ustar0000000000000000use 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.1/tests/ui-common/skip_with_other_options.stderr010064400017500001750000000002401353221400700232430ustar0000000000000000error: methods are not allowed for skipped fields --> $DIR/skip_with_other_options.rs:8:23 | 8 | #[structopt(skip, long)] | ^^^^ structopt-0.3.1/tests/ui-common/skip_without_default.rs010064400017500001750000000012351353440500700216550ustar0000000000000000// 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.1/tests/ui-common/skip_without_default.stderr010064400017500001750000000005631353221400700225330ustar0000000000000000error[E0277]: the trait bound `Kind: std::default::Default` is not satisfied --> $DIR/skip_without_default.rs:22:17 | 22 | #[structopt(skip)] | ^^^^ the trait `std::default::Default` is not implemented for `Kind` | = note: required by `std::default::Default::default` For more information about this error, try `rustc --explain E0277`. structopt-0.3.1/tests/ui-common/struct_flatten.rs010064400017500001750000000011171353440500700204600ustar0000000000000000// 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", flatten)] struct Opt { #[structopt(short)] s: String, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); } structopt-0.3.1/tests/ui-common/struct_flatten.stderr010064400017500001750000000002451353221400700213340ustar0000000000000000error: flatten is only allowed on fields --> $DIR/struct_flatten.rs:12:29 | 12 | #[structopt(name = "basic", flatten)] | ^^^^^^^ structopt-0.3.1/tests/ui-common/struct_parse.rs010064400017500001750000000011271353440500700201360ustar0000000000000000// 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.1/tests/ui-common/struct_parse.stderr010064400017500001750000000002611353221400700210070ustar0000000000000000error: parse attribute is only allowed on fields --> $DIR/struct_parse.rs:12:29 | 12 | #[structopt(name = "basic", parse(from_str))] | ^^^^^ structopt-0.3.1/tests/ui-common/struct_subcommand.rs010064400017500001750000000011221353440500700211470ustar0000000000000000// 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.1/tests/ui-common/struct_subcommand.stderr010064400017500001750000000002611353221400700220250ustar0000000000000000error: subcommand is only allowed on fields --> $DIR/struct_subcommand.rs:12:29 | 12 | #[structopt(name = "basic", subcommand)] | ^^^^^^^^^^ structopt-0.3.1/tests/ui-common/structopt_empty_attr.rs010064400017500001750000000011021353440500700217300ustar0000000000000000// 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.1/tests/ui-common/structopt_empty_attr.stderr010064400017500001750000000002061353221400700226070ustar0000000000000000error: expected parentheses after `structopt` --> $DIR/structopt_empty_attr.rs:14:7 | 14 | #[structopt] | ^^^^^^^^^ structopt-0.3.1/tests/ui-common/structopt_name_value_attr.rs010064400017500001750000000011141353440500700227110ustar0000000000000000// 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.1/tests/ui-common/structopt_name_value_attr.stderr010064400017500001750000000002061353221400700235650ustar0000000000000000error: expected parentheses --> $DIR/structopt_name_value_attr.rs:14:17 | 14 | #[structopt = "short"] | ^ structopt-0.3.1/tests/ui-common/subcommand_and_flatten.rs010064400017500001750000000015701353440500700221110ustar0000000000000000// 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.1/tests/ui-common/subcommand_and_flatten.stderr010064400017500001750000000003001353221400700227520ustar0000000000000000error: subcommand, flatten and skip cannot be used together --> $DIR/subcommand_and_flatten.rs:17:29 | 17 | #[structopt(subcommand, flatten)] | ^^^^^^^ structopt-0.3.1/tests/ui-common/subcommand_and_methods.rs010064400017500001750000000015651353440500700221230ustar0000000000000000// 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.1/tests/ui-common/subcommand_and_methods.stderr010064400017500001750000000002721353221400700227700ustar0000000000000000error: methods in attributes are not allowed for subcommand --> $DIR/subcommand_and_methods.rs:17:29 | 17 | #[structopt(subcommand, long)] | ^^^^ structopt-0.3.1/tests/ui-common/subcommand_and_parse.rs010064400017500001750000000016101353440500700215610ustar0000000000000000// 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.1/tests/ui-common/subcommand_and_parse.stderr010064400017500001750000000003051353221400700224340ustar0000000000000000error: parse attribute is not allowed for subcommand --> $DIR/subcommand_and_parse.rs:17:29 | 17 | #[structopt(subcommand, parse(from_occurrences))] | ^^^^^ structopt-0.3.1/tests/ui-common/tuple_struct.rs010064400017500001750000000010411353440500700201500ustar0000000000000000// 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.1/tests/ui-common/tuple_struct.stderr010064400017500001750000000002321353221400700210240ustar0000000000000000error: structopt only supports non-tuple structs and enums --> $DIR/tuple_struct.rs:11:10 | 11 | #[derive(StructOpt, Debug)] | ^^^^^^^^^ structopt-0.3.1/tests/ui-pre_1.39/opt_opt_nonpositional.rs010064400017500001750000000010731353440500700220300ustar0000000000000000// 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.1/tests/ui-pre_1.39/opt_opt_nonpositional.stderr010064400017500001750000000002471353221400700227050ustar0000000000000000error: Option> type is meaningless for positional argument --> $DIR/opt_opt_nonpositional.rs:14:8 | 14 | n: Option>, | ^^^^^^ structopt-0.3.1/tests/ui-pre_1.39/opt_vec_nonpositional.rs010064400017500001750000000010701353440500700220000ustar0000000000000000// 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.1/tests/ui-pre_1.39/opt_vec_nonpositional.stderr010064400017500001750000000002411353221400700226520ustar0000000000000000error: Option> type is meaningless for positional argument --> $DIR/opt_vec_nonpositional.rs:14:8 | 14 | n: Option>, | ^^^^^^ structopt-0.3.1/tests/ui-pre_1.39/subcommand_opt_opt.rs010064400017500001750000000015771353440500700212750ustar0000000000000000// 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.1/tests/ui-pre_1.39/subcommand_opt_opt.stderr010064400017500001750000000002441353221400700221360ustar0000000000000000error: Option> type is not allowed for subcommand --> $DIR/subcommand_opt_opt.rs:18:10 | 18 | cmd: Option>, | ^^^^^^ structopt-0.3.1/tests/ui-pre_1.39/subcommand_opt_vec.rs010064400017500001750000000015741353440500700212450ustar0000000000000000// 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.1/tests/ui-pre_1.39/subcommand_opt_vec.stderr010064400017500001750000000002361353221400700221120ustar0000000000000000error: Option> type is not allowed for subcommand --> $DIR/subcommand_opt_vec.rs:18:10 | 18 | cmd: Option>, | ^^^^^^ structopt-0.3.1/.cargo_vcs_info.json0000644000000001120000000000000131350ustar00{ "git": { "sha1": "e0f74b0f62677367f2789e4ef70bacf7390f5745" } } structopt-0.3.1/Cargo.lock0000644000000665520000000000000111340ustar00# This file is automatically @generated by Cargo. # It is not intended for manual editing. [[package]] name = "ansi_term" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "arrayref" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "arrayvec" version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "atty" version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "backtrace" version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "backtrace-sys" version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "base64" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "bitflags" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "blake2b_simd" version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "byteorder" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cc" version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cfg-if" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "clap" version = "2.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "clippy 0.0.302 (registry+https://github.com/rust-lang/crates.io-index)", "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "clippy" version = "0.0.302" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cloudabi" version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "constant_time_eq" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "crossbeam-utils" version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "dirs" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "redox_users 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "failure" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "failure_derive" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "fuchsia-cprng" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "glob" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "heck" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "itoa" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "kernel32-sys" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" version = "0.2.62" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "nodrop" version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "proc-macro-error" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "proc-macro2" version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "proc-macro2" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "quote" version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "quote" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rand_core" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rand_core" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rand_os" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rdrand" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "redox_syscall" version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "redox_users" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "rust-argon2 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rust-argon2" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "blake2b_simd 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-demangle" version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "ryu" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde_derive 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive" version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "strsim" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "structopt" version = "0.3.1" dependencies = [ "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "structopt-derive 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "trybuild 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "structopt-derive" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro-error 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "syn" version = "0.15.44" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "syn" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "synstructure" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "term" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "term_size" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "termcolor" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "wincolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "textwrap" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "toml" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "trybuild" version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "unicode-segmentation" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "unicode-width" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "unicode-xid" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "unicode-xid" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "vec_map" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "version_check" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "winapi" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "winapi" version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "winapi-build" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "winapi-util" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "wincolor" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "yaml-rust" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" "checksum arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d73f9beda665eaa98ab9e4f7442bd4e7de6652587de55b2525e52e29c1b0ba" "checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" "checksum backtrace 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)" = "5180c5a20655b14a819b652fd2378fa5f1697b6c9ddad3e695c2f9cedf6df4e2" "checksum backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "82a830b4ef2d1124a711c71d263c5abdc710ef8e907bd508c88be475cebc422b" "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" "checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd" "checksum blake2b_simd 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "5850aeee1552f495dd0250014cf64b82b7c8879a89d83b33bbdace2cc4f63182" "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" "checksum cc 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)" = "a61c7bce55cd2fae6ec8cb935ebd76256c2959a1f95790f6118a441c2cd5b406" "checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33" "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" "checksum clippy 0.0.302 (registry+https://github.com/rust-lang/crates.io-index)" = "d911ee15579a3f50880d8c1d59ef6e79f9533127a3bd342462f5d584f5e8c294" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "995a44c877f9212528ccc74b21a232f66ad69001e40ede5bcee2ac9ef2657120" "checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" "checksum dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" "checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba" "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" "checksum proc-macro-error 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "aeccfe4d5d8ea175d5f0e4a2ad0637e0f4121d63bd99d356fb1f39ab2e7c6097" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" "checksum proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "175a40b9cf564ce9bf050654633dbf339978706b8ead1a907bb970b63185dd95" "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" "checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" "checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" "checksum redox_users 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ecedbca3bf205f8d8f5c2b44d83cd0690e39ee84b951ed649e9f1841132b66d" "checksum rust-argon2 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ca4eaef519b494d1f2848fc602d18816fed808a981aedf4f1f00ceb7c9d32cf" "checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" "checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997" "checksum serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)" = "fec2851eb56d010dc9a21b89ca53ee75e6528bab60c11e89d38390904982da9f" "checksum serde_derive 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)" = "cb4dc18c61206b08dc98216c98faa0232f4337e1e1b8574551d5bad29ea1b425" "checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704" "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" "checksum structopt-derive 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ae9e5165d463a0dea76967d021f8d0f9316057bf5163aa2a4843790e842ff37" "checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" "checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf" "checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" "checksum term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42" "checksum term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e5b9a66db815dcfd2da92db471106457082577c3c278d4138ab3e3b4e189327" "checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" "checksum toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c7aabe75941d914b72bf3e5d3932ed92ce0664d49d8432305a8b547c37227724" "checksum trybuild 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c718030bb5c88b65994c4200d929d10628d653c7798a35012f8ff4c4211624a8" "checksum unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1967f4cdfc355b37fd76d2a954fb2ed3871034eb4f26d60537d88795cfc332a9" "checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum wincolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "96f5016b18804d24db43cebf3c77269e7569b8954a8464501c216cc5e070eaa9" "checksum yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992"