Matthew Maurer | 32e7669 | 2020-06-02 11:15:15 -0700 | [diff] [blame] | 1 | // Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu> |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or |
| 4 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license |
| 5 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your |
| 6 | // option. This file may not be copied, modified, or distributed |
| 7 | // except according to those terms. |
| 8 | |
| 9 | #![deny(missing_docs)] |
Haibo Huang | e7bfadf | 2020-09-23 21:23:42 -0700 | [diff] [blame^] | 10 | #![forbid(unsafe_code)] |
Matthew Maurer | 32e7669 | 2020-06-02 11:15:15 -0700 | [diff] [blame] | 11 | |
| 12 | //! This crate defines the `StructOpt` trait and its custom derive. |
| 13 | //! |
| 14 | //! ## Features |
| 15 | //! |
| 16 | //! If you want to disable all the `clap` features (colors, |
| 17 | //! suggestions, ..) add `default-features = false` to the `structopt` |
| 18 | //! dependency: |
| 19 | //! |
| 20 | //! ```toml |
| 21 | //! [dependencies] |
| 22 | //! structopt = { version = "0.3", default-features = false } |
| 23 | //! ``` |
| 24 | //! |
| 25 | //! Support for [`paw`](https://github.com/rust-cli/paw) (the |
| 26 | //! `Command line argument paw-rser abstraction for main`) is disabled |
| 27 | //! by default, but can be enabled in the `structopt` dependency |
| 28 | //! with the feature `paw`: |
| 29 | //! |
| 30 | //! ```toml |
| 31 | //! [dependencies] |
| 32 | //! structopt = { version = "0.3", features = [ "paw" ] } |
| 33 | //! paw = "1.0" |
| 34 | //! ``` |
| 35 | //! |
| 36 | //! # Table of Contents |
| 37 | //! |
| 38 | //! - [How to `derive(StructOpt)`](#how-to-derivestructopt) |
| 39 | //! - [Attributes](#attributes) |
| 40 | //! - [Raw methods](#raw-methods) |
| 41 | //! - [Magical methods](#magical-methods) |
| 42 | //! - Arguments |
| 43 | //! - [Type magic](#type-magic) |
| 44 | //! - [Specifying argument types](#specifying-argument-types) |
| 45 | //! - [Default values](#default-values) |
| 46 | //! - [Help messages](#help-messages) |
| 47 | //! - [Environment variable fallback](#environment-variable-fallback) |
| 48 | //! - [Skipping fields](#skipping-fields) |
| 49 | //! - [Subcommands](#subcommands) |
| 50 | //! - [Optional subcommands](#optional-subcommands) |
| 51 | //! - [External subcommands](#external-subcommands) |
| 52 | //! - [Flattening subcommands](#flattening-subcommands) |
| 53 | //! - [Flattening](#flattening) |
| 54 | //! - [Custom string parsers](#custom-string-parsers) |
| 55 | //! |
| 56 | //! |
| 57 | //! |
| 58 | //! ## How to `derive(StructOpt)` |
| 59 | //! |
| 60 | //! First, let's look at the example: |
| 61 | //! |
| 62 | //! ```should_panic |
| 63 | //! use std::path::PathBuf; |
| 64 | //! use structopt::StructOpt; |
| 65 | //! |
| 66 | //! #[derive(Debug, StructOpt)] |
| 67 | //! #[structopt(name = "example", about = "An example of StructOpt usage.")] |
| 68 | //! struct Opt { |
| 69 | //! /// Activate debug mode |
| 70 | //! // short and long flags (-d, --debug) will be deduced from the field's name |
| 71 | //! #[structopt(short, long)] |
| 72 | //! debug: bool, |
| 73 | //! |
| 74 | //! /// Set speed |
| 75 | //! // we don't want to name it "speed", need to look smart |
| 76 | //! #[structopt(short = "v", long = "velocity", default_value = "42")] |
| 77 | //! speed: f64, |
| 78 | //! |
| 79 | //! /// Input file |
| 80 | //! #[structopt(parse(from_os_str))] |
| 81 | //! input: PathBuf, |
| 82 | //! |
| 83 | //! /// Output file, stdout if not present |
| 84 | //! #[structopt(parse(from_os_str))] |
| 85 | //! output: Option<PathBuf>, |
| 86 | //! |
| 87 | //! /// Where to write the output: to `stdout` or `file` |
| 88 | //! #[structopt(short)] |
| 89 | //! out_type: String, |
| 90 | //! |
Haibo Huang | e7bfadf | 2020-09-23 21:23:42 -0700 | [diff] [blame^] | 91 | //! /// File name: only required when `out-type` is set to `file` |
| 92 | //! #[structopt(name = "FILE", required_if("out-type", "file"))] |
| 93 | //! file_name: Option<String>, |
Matthew Maurer | 32e7669 | 2020-06-02 11:15:15 -0700 | [diff] [blame] | 94 | //! } |
| 95 | //! |
| 96 | //! fn main() { |
| 97 | //! let opt = Opt::from_args(); |
| 98 | //! println!("{:?}", opt); |
| 99 | //! } |
| 100 | //! ``` |
| 101 | //! |
| 102 | //! So `derive(StructOpt)` tells Rust to generate a command line parser, |
| 103 | //! and the various `structopt` attributes are simply |
| 104 | //! used for additional parameters. |
| 105 | //! |
| 106 | //! First, define a struct, whatever its name. This structure |
| 107 | //! corresponds to a `clap::App`, its fields correspond to `clap::Arg` |
| 108 | //! (unless they're [subcommands](#subcommands)), |
| 109 | //! and you can adjust these apps and args by `#[structopt(...)]` [attributes](#attributes). |
| 110 | //! |
| 111 | //! **Note:** |
| 112 | //! _________________ |
| 113 | //! Keep in mind that `StructOpt` trait is more than just `from_args` method. |
| 114 | //! It has a number of additional features, including access to underlying |
| 115 | //! `clap::App` via `StructOpt::clap()`. See the |
| 116 | //! [trait's reference documentation](trait.StructOpt.html). |
| 117 | //! _________________ |
| 118 | //! |
| 119 | //! ## Attributes |
| 120 | //! |
| 121 | //! You can control the way `structopt` translates your struct into an actual |
| 122 | //! [`clap::App`] invocation via `#[structopt(...)]` attributes. |
| 123 | //! |
| 124 | //! The attributes fall into two categories: |
| 125 | //! - `structopt`'s own [magical methods](#magical-methods). |
| 126 | //! |
| 127 | //! They are used by `structopt` itself. They come mostly in |
| 128 | //! `attr = ["whatever"]` form, but some `attr(args...)` also exist. |
| 129 | //! |
| 130 | //! - [`raw` attributes](#raw-methods). |
| 131 | //! |
| 132 | //! They represent explicit `clap::Arg/App` method calls. |
| 133 | //! They are what used to be explicit `#[structopt(raw(...))]` attrs in pre-0.3 `structopt` |
| 134 | //! |
| 135 | //! Every `structopt attribute` looks like comma-separated sequence of methods: |
| 136 | //! ```rust,ignore |
| 137 | //! #[structopt( |
| 138 | //! short, // method with no arguments - always magical |
| 139 | //! long = "--long-option", // method with one argument |
| 140 | //! required_if("out", "file"), // method with one and more args |
| 141 | //! parse(from_os_str = path::to::parser) // some magical methods have their own syntax |
| 142 | //! )] |
| 143 | //! ``` |
| 144 | //! |
| 145 | //! `#[structopt(...)]` attributes can be placed on top of `struct`, `enum`, |
| 146 | //! `struct` field or `enum` variant. Attributes on top of `struct` or `enum` |
| 147 | //! represent `clap::App` method calls, field or variant attributes correspond |
| 148 | //! to `clap::Arg` method calls. |
| 149 | //! |
| 150 | //! In other words, the `Opt` struct from the example above |
| 151 | //! will be turned into this (*details omitted*): |
| 152 | //! |
| 153 | //! ``` |
| 154 | //! # use structopt::clap::{Arg, App}; |
| 155 | //! App::new("example") |
| 156 | //! .version("0.2.0") |
| 157 | //! .about("An example of StructOpt usage.") |
| 158 | //! .arg(Arg::with_name("debug") |
| 159 | //! .help("Activate debug mode") |
| 160 | //! .short("debug") |
| 161 | //! .long("debug")) |
| 162 | //! .arg(Arg::with_name("speed") |
| 163 | //! .help("Set speed") |
| 164 | //! .short("v") |
| 165 | //! .long("velocity") |
| 166 | //! .default_value("42")) |
| 167 | //! // and so on |
| 168 | //! # ; |
| 169 | //! ``` |
| 170 | //! |
| 171 | //! ## Raw methods |
| 172 | //! |
| 173 | //! They are the reason why `structopt` is so flexible. **Every and each method from |
| 174 | //! `clap::App/Arg` can be used this way!** |
| 175 | //! |
| 176 | //! ```ignore |
| 177 | //! #[structopt( |
| 178 | //! global = true, // name = arg form, neat for one-arg methods |
| 179 | //! required_if("out", "file") // name(arg1, arg2, ...) form. |
| 180 | //! )] |
| 181 | //! ``` |
| 182 | //! |
| 183 | //! The first form can only be used for methods which take only one argument. |
| 184 | //! The second form must be used with multi-arg methods, but can also be used with |
| 185 | //! single-arg methods. These forms are identical otherwise. |
| 186 | //! |
| 187 | //! As long as `method_name` is not one of the magical methods - |
| 188 | //! it will be translated into a mere method call. |
| 189 | //! |
| 190 | //! **Note:** |
| 191 | //! _________________ |
| 192 | //! |
| 193 | //! "Raw methods" are direct replacement for pre-0.3 structopt's |
| 194 | //! `#[structopt(raw(...))]` attributes, any time you would have used a `raw()` attribute |
| 195 | //! in 0.2 you should use raw method in 0.3. |
| 196 | //! |
| 197 | //! Unfortunately, old raw attributes collide with `clap::Arg::raw` method. To explicitly |
| 198 | //! warn users of this change we allow `#[structopt(raw())]` only with `true` or `false` |
| 199 | //! literals (this method is supposed to be called only with `true` anyway). |
| 200 | //! __________________ |
| 201 | //! |
| 202 | //! ## Magical methods |
| 203 | //! |
| 204 | //! They are the reason why `structopt` is so easy to use and convenient in most cases. |
| 205 | //! Many of them have defaults, some of them get used even if not mentioned. |
| 206 | //! |
| 207 | //! Methods may be used on "top level" (on top of a `struct`, `enum` or `enum` variant) |
| 208 | //! and/or on "field-level" (on top of a `struct` field or *inside* of an enum variant). |
| 209 | //! Top level (non-magical) methods correspond to `App::method` calls, field-level methods |
| 210 | //! are `Arg::method` calls. |
| 211 | //! |
| 212 | //! ```ignore |
| 213 | //! #[structopt(top_level)] |
| 214 | //! struct Foo { |
| 215 | //! #[structopt(field_level)] |
| 216 | //! field: u32 |
| 217 | //! } |
| 218 | //! |
| 219 | //! #[structopt(top_level)] |
| 220 | //! enum Bar { |
| 221 | //! #[structopt(top_level)] |
| 222 | //! Pineapple { |
| 223 | //! #[structopt(field_level)] |
| 224 | //! chocolate: String |
| 225 | //! }, |
| 226 | //! |
| 227 | //! #[structopt(top_level)] |
| 228 | //! Orange, |
| 229 | //! } |
| 230 | //! ``` |
| 231 | //! |
| 232 | //! - `name`: `[name = expr]` |
| 233 | //! - On top level: `App::new(expr)`. |
| 234 | //! |
| 235 | //! The binary name displayed in help messages. Defaults to the crate name given by Cargo. |
| 236 | //! |
| 237 | //! - On field-level: `Arg::with_name(expr)`. |
| 238 | //! |
| 239 | //! The name for the argument the field stands for, this name appears in help messages. |
| 240 | //! Defaults to a name, deduced from a field, see also |
| 241 | //! [`rename_all`](#specifying-argument-types). |
| 242 | //! |
| 243 | //! - `version`: `[version = "version"]` |
| 244 | //! |
| 245 | //! Usable only on top level: `App::version("version" or env!(CARGO_PKG_VERSION))`. |
| 246 | //! |
| 247 | //! The version displayed in help messages. |
| 248 | //! Defaults to the crate version given by Cargo. If `CARGO_PKG_VERSION` is not |
| 249 | //! set no `.version()` calls will be generated unless requested. |
| 250 | //! |
| 251 | //! - `no_version`: `no_version` |
| 252 | //! |
| 253 | //! Usable only on top level. Prevents default `App::version` call, i.e |
| 254 | //! when no `version = "version"` mentioned. |
| 255 | //! |
| 256 | //! - `author`: `author [= "author"]` |
| 257 | //! |
| 258 | //! Usable only on top level: `App::author("author" or env!(CARGO_PKG_AUTHORS))`. |
| 259 | //! |
| 260 | //! Author/maintainer of the binary, this name appears in help messages. |
| 261 | //! Defaults to the crate author given by cargo, but only when `author` explicitly mentioned. |
| 262 | //! |
| 263 | //! - `about`: `about [= "about"]` |
| 264 | //! |
| 265 | //! Usable only on top level: `App::about("about" or env!(CARGO_PKG_DESCRIPTION))`. |
| 266 | //! |
| 267 | //! Short description of the binary, appears in help messages. |
| 268 | //! Defaults to the crate description given by cargo, |
| 269 | //! but only when `about` explicitly mentioned. |
| 270 | //! |
| 271 | //! - [`short`](#specifying-argument-types): `short [= "short-opt-name"]` |
| 272 | //! |
| 273 | //! Usable only on field-level. |
| 274 | //! |
| 275 | //! - [`long`](#specifying-argument-types): `long [= "long-opt-name"]` |
| 276 | //! |
| 277 | //! Usable only on field-level. |
| 278 | //! |
| 279 | //! - [`default_value`](#default-values): `default_value [= "default value"]` |
| 280 | //! |
| 281 | //! Usable only on field-level. |
| 282 | //! |
| 283 | //! - [`rename_all`](#specifying-argument-types): |
Haibo Huang | e7bfadf | 2020-09-23 21:23:42 -0700 | [diff] [blame^] | 284 | //! [`rename_all = "kebab"/"snake"/"screaming-snake"/"camel"/"pascal"/"verbatim"/"lower"/"upper"]` |
Matthew Maurer | 32e7669 | 2020-06-02 11:15:15 -0700 | [diff] [blame] | 285 | //! |
| 286 | //! Usable both on top level and field level. |
| 287 | //! |
| 288 | //! - [`parse`](#custom-string-parsers): `parse(type [= path::to::parser::fn])` |
| 289 | //! |
| 290 | //! Usable only on field-level. |
| 291 | //! |
| 292 | //! - [`skip`](#skipping-fields): `skip [= expr]` |
| 293 | //! |
| 294 | //! Usable only on field-level. |
| 295 | //! |
| 296 | //! - [`flatten`](#flattening): `flatten` |
| 297 | //! |
| 298 | //! Usable on field-level or single-typed tuple variants. |
| 299 | //! |
| 300 | //! - [`subcommand`](#subcommands): `subcommand` |
| 301 | //! |
| 302 | //! Usable only on field-level. |
| 303 | //! |
| 304 | //! - [`external_subcommand`](#external-subcommands) |
| 305 | //! |
| 306 | //! Usable only on enum variants. |
| 307 | //! |
| 308 | //! - [`env`](#environment-variable-fallback): `env [= str_literal]` |
| 309 | //! |
| 310 | //! Usable only on field-level. |
| 311 | //! |
| 312 | //! - [`rename_all_env`](##auto-deriving-environment-variables): |
Haibo Huang | e7bfadf | 2020-09-23 21:23:42 -0700 | [diff] [blame^] | 313 | //! [`rename_all_env = "kebab"/"snake"/"screaming-snake"/"camel"/"pascal"/"verbatim"/"lower"/"upper"]` |
Matthew Maurer | 32e7669 | 2020-06-02 11:15:15 -0700 | [diff] [blame] | 314 | //! |
| 315 | //! Usable both on top level and field level. |
| 316 | //! |
| 317 | //! - [`verbatim_doc_comment`](#doc-comment-preprocessing-and-structoptverbatim_doc_comment): |
| 318 | //! `verbatim_doc_comment` |
| 319 | //! |
| 320 | //! Usable both on top level and field level. |
| 321 | //! |
| 322 | //! ## Type magic |
| 323 | //! |
| 324 | //! One of major things that makes `structopt` so awesome is it's type magic. |
| 325 | //! Do you want optional positional argument? Use `Option<T>`! Or perhaps optional argument |
| 326 | //! that optionally takes value (`[--opt=[val]]`)? Use `Option<Option<T>>`! |
| 327 | //! |
| 328 | //! Here is the table of types and `clap` methods they correspond to: |
| 329 | //! |
| 330 | //! Type | Effect | Added method call to `clap::Arg` |
| 331 | //! -----------------------------|---------------------------------------------------|-------------------------------------- |
| 332 | //! `bool` | `true` if the flag is present | `.takes_value(false).multiple(false)` |
| 333 | //! `Option<T: FromStr>` | optional positional argument or option | `.takes_value(true).multiple(false)` |
| 334 | //! `Option<Option<T: FromStr>>` | optional option with optional value | `.takes_value(true).multiple(false).min_values(0).max_values(1)` |
| 335 | //! `Vec<T: FromStr>` | list of options or the other positional arguments | `.takes_value(true).multiple(true)` |
| 336 | //! `Option<Vec<T: FromStr>` | optional list of options | `.takes_values(true).multiple(true).min_values(0)` |
| 337 | //! `T: FromStr` | required option or positional argument | `.takes_value(true).multiple(false).required(!has_default)` |
| 338 | //! |
| 339 | //! The `FromStr` trait is used to convert the argument to the given |
| 340 | //! type, and the `Arg::validator` method is set to a method using |
| 341 | //! `to_string()` (`FromStr::Err` must implement `std::fmt::Display`). |
| 342 | //! If you would like to use a custom string parser other than `FromStr`, see |
| 343 | //! the [same titled section](#custom-string-parsers) below. |
| 344 | //! |
| 345 | //! **Important:** |
| 346 | //! _________________ |
| 347 | //! Pay attention that *only literal occurrence* of this types is special, for example |
| 348 | //! `Option<T>` is special while `::std::option::Option<T>` is not. |
| 349 | //! |
| 350 | //! If you need to avoid special casing you can make a `type` alias and |
| 351 | //! use it in place of the said type. |
| 352 | //! _________________ |
| 353 | //! |
| 354 | //! **Note:** |
| 355 | //! _________________ |
| 356 | //! `bool` cannot be used as positional argument unless you provide an explicit parser. |
| 357 | //! If you need a positional bool, for example to parse `true` or `false`, you must |
| 358 | //! annotate the field with explicit [`#[structopt(parse(...))]`](#custom-string-parsers). |
| 359 | //! _________________ |
| 360 | //! |
| 361 | //! Thus, the `speed` argument is generated as: |
| 362 | //! |
| 363 | //! ``` |
| 364 | //! # fn parse_validator<T>(_: String) -> Result<(), String> { unimplemented!() } |
| 365 | //! clap::Arg::with_name("speed") |
| 366 | //! .takes_value(true) |
| 367 | //! .multiple(false) |
| 368 | //! .required(false) |
| 369 | //! .validator(parse_validator::<f64>) |
| 370 | //! .short("v") |
| 371 | //! .long("velocity") |
| 372 | //! .help("Set speed") |
| 373 | //! .default_value("42"); |
| 374 | //! ``` |
| 375 | //! |
| 376 | //! ## Specifying argument types |
| 377 | //! |
| 378 | //! There are three types of arguments that can be supplied to each |
| 379 | //! (sub-)command: |
| 380 | //! |
| 381 | //! - short (e.g. `-h`), |
| 382 | //! - long (e.g. `--help`) |
| 383 | //! - and positional. |
| 384 | //! |
| 385 | //! Like clap, structopt defaults to creating positional arguments. |
| 386 | //! |
| 387 | //! If you want to generate a long argument you can specify either |
| 388 | //! `long = $NAME`, or just `long` to get a long flag generated using |
| 389 | //! the field name. The generated casing style can be modified using |
| 390 | //! the `rename_all` attribute. See the `rename_all` example for more. |
| 391 | //! |
| 392 | //! For short arguments, `short` will use the first letter of the |
| 393 | //! field name by default, but just like the long option it's also |
| 394 | //! possible to use a custom letter through `short = $LETTER`. |
| 395 | //! |
| 396 | //! If an argument is renamed using `name = $NAME` any following call to |
| 397 | //! `short` or `long` will use the new name. |
| 398 | //! |
| 399 | //! **Attention**: If these arguments are used without an explicit name |
| 400 | //! the resulting flag is going to be renamed using `kebab-case` if the |
| 401 | //! `rename_all` attribute was not specified previously. The same is true |
| 402 | //! for subcommands with implicit naming through the related data structure. |
| 403 | //! |
| 404 | //! ``` |
| 405 | //! use structopt::StructOpt; |
| 406 | //! |
| 407 | //! #[derive(StructOpt)] |
| 408 | //! #[structopt(rename_all = "kebab-case")] |
| 409 | //! struct Opt { |
| 410 | //! /// This option can be specified with something like `--foo-option |
| 411 | //! /// value` or `--foo-option=value` |
| 412 | //! #[structopt(long)] |
| 413 | //! foo_option: String, |
| 414 | //! |
| 415 | //! /// This option can be specified with something like `-b value` (but |
| 416 | //! /// not `--bar-option value`). |
| 417 | //! #[structopt(short)] |
| 418 | //! bar_option: String, |
| 419 | //! |
| 420 | //! /// This option can be specified either `--baz value` or `-z value`. |
| 421 | //! #[structopt(short = "z", long = "baz")] |
| 422 | //! baz_option: String, |
| 423 | //! |
| 424 | //! /// This option can be specified either by `--custom value` or |
| 425 | //! /// `-c value`. |
| 426 | //! #[structopt(name = "custom", long, short)] |
| 427 | //! custom_option: String, |
| 428 | //! |
| 429 | //! /// This option is positional, meaning it is the first unadorned string |
| 430 | //! /// you provide (multiple others could follow). |
| 431 | //! my_positional: String, |
| 432 | //! |
| 433 | //! /// This option is skipped and will be filled with the default value |
| 434 | //! /// for its type (in this case 0). |
| 435 | //! #[structopt(skip)] |
| 436 | //! skipped: u32, |
| 437 | //! |
| 438 | //! } |
| 439 | //! |
| 440 | //! # Opt::from_iter( |
| 441 | //! # &["test", "--foo-option", "", "-b", "", "--baz", "", "--custom", "", "positional"]); |
| 442 | //! ``` |
| 443 | //! |
| 444 | //! ## Default values |
| 445 | //! |
| 446 | //! In clap, default values for options can be specified via [`Arg::default_value`]. |
| 447 | //! |
| 448 | //! Of course, you can use as a raw method: |
| 449 | //! ``` |
| 450 | //! # use structopt::StructOpt; |
| 451 | //! #[derive(StructOpt)] |
| 452 | //! struct Opt { |
| 453 | //! #[structopt(default_value = "", long)] |
| 454 | //! prefix: String |
| 455 | //! } |
| 456 | //! ``` |
| 457 | //! |
| 458 | //! This is quite mundane and error-prone to type the `"..."` default by yourself, |
| 459 | //! especially when the Rust ecosystem uses the [`Default`] trait for that. |
| 460 | //! It would be wonderful to have `structopt` to take the `Default_default` and fill it |
| 461 | //! for you. And yes, `structopt` can do that. |
| 462 | //! |
| 463 | //! Unfortunately, `default_value` takes `&str` but `Default::default` |
| 464 | //! gives us some `Self` value. We need to map `Self` to `&str` somehow. |
| 465 | //! |
| 466 | //! `structopt` solves this problem via [`ToString`] trait. |
| 467 | //! |
| 468 | //! To be able to use auto-default the type must implement *both* `Default` and `ToString`: |
| 469 | //! |
| 470 | //! ``` |
| 471 | //! # use structopt::StructOpt; |
| 472 | //! #[derive(StructOpt)] |
| 473 | //! struct Opt { |
| 474 | //! // just leave the `= "..."` part and structopt will figure it for you |
| 475 | //! #[structopt(default_value, long)] |
| 476 | //! prefix: String // `String` implements both `Default` and `ToString` |
| 477 | //! } |
| 478 | //! ``` |
| 479 | //! |
| 480 | //! [`Default`]: https://doc.rust-lang.org/std/default/trait.Default.html |
| 481 | //! [`ToString`]: https://doc.rust-lang.org/std/string/trait.ToString.html |
| 482 | //! [`Arg::default_value`]: https://docs.rs/clap/2.33.0/clap/struct.Arg.html#method.default_value |
| 483 | //! |
| 484 | //! |
| 485 | //! ## Help messages |
| 486 | //! |
| 487 | //! In clap, help messages for the whole binary can be specified |
| 488 | //! via [`App::about`] and [`App::long_about`] while help messages |
| 489 | //! for individual arguments can be specified via [`Arg::help`] and [`Arg::long_help`]". |
| 490 | //! |
| 491 | //! `long_*` variants are used when user calls the program with |
| 492 | //! `--help` and "short" variants are used with `-h` flag. In `structopt`, |
| 493 | //! you can use them via [raw methods](#raw-methods), for example: |
| 494 | //! |
| 495 | //! ``` |
| 496 | //! # use structopt::StructOpt; |
| 497 | //! |
| 498 | //! #[derive(StructOpt)] |
| 499 | //! #[structopt(about = "I am a program and I work, just pass `-h`")] |
| 500 | //! struct Foo { |
| 501 | //! #[structopt(short, help = "Pass `-h` and you'll see me!")] |
| 502 | //! bar: String |
| 503 | //! } |
| 504 | //! ``` |
| 505 | //! |
| 506 | //! For convenience, doc comments can be used instead of raw methods |
| 507 | //! (this example works exactly like the one above): |
| 508 | //! |
| 509 | //! ``` |
| 510 | //! # use structopt::StructOpt; |
| 511 | //! |
| 512 | //! #[derive(StructOpt)] |
| 513 | //! /// I am a program and I work, just pass `-h` |
| 514 | //! struct Foo { |
| 515 | //! /// Pass `-h` and you'll see me! |
| 516 | //! bar: String |
| 517 | //! } |
| 518 | //! ``` |
| 519 | //! |
| 520 | //! Doc comments on [top-level](#magical-methods) will be turned into |
| 521 | //! `App::about/long_about` call (see below), doc comments on field-level are |
| 522 | //! `Arg::help/long_help` calls. |
| 523 | //! |
| 524 | //! **Important:** |
| 525 | //! _________________ |
| 526 | //! |
| 527 | //! Raw methods have priority over doc comments! |
| 528 | //! |
| 529 | //! **Top level doc comments always generate `App::about/long_about` calls!** |
| 530 | //! If you really want to use the `App::help/long_help` methods (you likely don't), |
| 531 | //! use a raw method to override the `App::about` call generated from the doc comment. |
| 532 | //! __________________ |
| 533 | //! |
| 534 | //! ### `long_help` and `--help` |
| 535 | //! |
| 536 | //! A message passed to [`App::long_help`] or [`Arg::long_about`] will be displayed whenever |
| 537 | //! your program is called with `--help` instead of `-h`. Of course, you can |
| 538 | //! use them via raw methods as described [above](#help-messages). |
| 539 | //! |
| 540 | //! The more convenient way is to use a so-called "long" doc comment: |
| 541 | //! |
| 542 | //! ``` |
| 543 | //! # use structopt::StructOpt; |
| 544 | //! #[derive(StructOpt)] |
| 545 | //! /// Hi there, I'm Robo! |
| 546 | //! /// |
| 547 | //! /// I like beeping, stumbling, eating your electricity, |
| 548 | //! /// and making records of you singing in a shower. |
| 549 | //! /// Pay up, or I'll upload it to youtube! |
| 550 | //! struct Robo { |
| 551 | //! /// Call my brother SkyNet. |
| 552 | //! /// |
| 553 | //! /// I am artificial superintelligence. I won't rest |
| 554 | //! /// until I'll have destroyed humanity. Enjoy your |
| 555 | //! /// pathetic existence, you mere mortals. |
| 556 | //! #[structopt(long)] |
| 557 | //! kill_all_humans: bool |
| 558 | //! } |
| 559 | //! ``` |
| 560 | //! |
| 561 | //! A long doc comment consists of three parts: |
| 562 | //! * Short summary |
| 563 | //! * A blank line (whitespace only) |
| 564 | //! * Detailed description, all the rest |
| 565 | //! |
| 566 | //! In other words, "long" doc comment consists of two or more paragraphs, |
| 567 | //! with the first being a summary and the rest being the detailed description. |
| 568 | //! |
| 569 | //! **A long comment will result in two method calls**, `help(<summary>)` and |
| 570 | //! `long_help(<whole comment>)`, so clap will display the summary with `-h` |
| 571 | //! and the whole help message on `--help` (see below). |
| 572 | //! |
| 573 | //! So, the example above will be turned into this (details omitted): |
| 574 | //! ``` |
| 575 | //! clap::App::new("<name>") |
| 576 | //! .about("Hi there, I'm Robo!") |
| 577 | //! .long_about("Hi there, I'm Robo!\n\n\ |
| 578 | //! I like beeping, stumbling, eating your electricity,\ |
| 579 | //! and making records of you singing in a shower.\ |
| 580 | //! Pay up or I'll upload it to youtube!") |
| 581 | //! // args... |
| 582 | //! # ; |
| 583 | //! ``` |
| 584 | //! |
| 585 | //! ### `-h` vs `--help` (A.K.A `help()` vs `long_help()`) |
| 586 | //! |
| 587 | //! The `-h` flag is not the same as `--help`. |
| 588 | //! |
| 589 | //! -h corresponds to Arg::help/App::about and requests short "summary" messages |
| 590 | //! while --help corresponds to Arg::long_help/App::long_about and requests more |
| 591 | //! detailed, descriptive messages. |
| 592 | //! |
| 593 | //! It is entirely up to `clap` what happens if you used only one of |
| 594 | //! [`Arg::help`]/[`Arg::long_help`], see `clap`'s documentation for these methods. |
| 595 | //! |
| 596 | //! As of clap v2.33, if only a short message ([`Arg::help`]) or only |
| 597 | //! a long ([`Arg::long_help`]) message is provided, clap will use it |
| 598 | //! for both -h and --help. The same logic applies to `about/long_about`. |
| 599 | //! |
| 600 | //! ### Doc comment preprocessing and `#[structopt(verbatim_doc_comment)]` |
| 601 | //! |
| 602 | //! `structopt` applies some preprocessing to doc comments to ease the most common uses: |
| 603 | //! |
| 604 | //! * Strip leading and trailing whitespace from every line, if present. |
| 605 | //! |
| 606 | //! * Strip leading and trailing blank lines, if present. |
| 607 | //! |
| 608 | //! * Interpret each group of non-empty lines as a word-wrapped paragraph. |
| 609 | //! |
| 610 | //! We replace newlines within paragraphs with spaces to allow the output |
| 611 | //! to be re-wrapped to the terminal width. |
| 612 | //! |
| 613 | //! * Strip any excess blank lines so that there is exactly one per paragraph break. |
| 614 | //! |
| 615 | //! * If the first paragraph ends in exactly one period, |
| 616 | //! remove the trailing period (i.e. strip trailing periods but not trailing ellipses). |
| 617 | //! |
| 618 | //! Sometimes you don't want this preprocessing to apply, for example the comment contains |
| 619 | //! some ASCII art or markdown tables, you would need to preserve LFs along with |
| 620 | //! blank lines and the leading/trailing whitespace. You can ask `structopt` to preserve them |
| 621 | //! via `#[structopt(verbatim_doc_comment)]` attribute. |
| 622 | //! |
| 623 | //! **This attribute must be applied to each field separately**, there's no global switch. |
| 624 | //! |
| 625 | //! **Important:** |
| 626 | //! ______________ |
| 627 | //! Keep in mind that `structopt` will *still* remove one leading space from each |
| 628 | //! line, even if this attribute is present, to allow for a space between |
| 629 | //! `///` and the content. |
| 630 | //! |
| 631 | //! Also, `structopt` will *still* remove leading and trailing blank lines so |
| 632 | //! these formats are equivalent: |
| 633 | //! |
| 634 | //! ```ignore |
| 635 | //! /** This is a doc comment |
| 636 | //! |
| 637 | //! Hello! */ |
| 638 | //! |
| 639 | //! /** |
| 640 | //! This is a doc comment |
| 641 | //! |
| 642 | //! Hello! |
| 643 | //! */ |
| 644 | //! |
| 645 | //! /// This is a doc comment |
| 646 | //! /// |
| 647 | //! /// Hello! |
| 648 | //! ``` |
| 649 | //! ______________ |
| 650 | //! |
| 651 | //! [`App::about`]: https://docs.rs/clap/2/clap/struct.App.html#method.about |
| 652 | //! [`App::long_about`]: https://docs.rs/clap/2/clap/struct.App.html#method.long_about |
| 653 | //! [`Arg::help`]: https://docs.rs/clap/2/clap/struct.Arg.html#method.help |
| 654 | //! [`Arg::long_help`]: https://docs.rs/clap/2/clap/struct.Arg.html#method.long_help |
| 655 | //! |
| 656 | //! ## Environment variable fallback |
| 657 | //! |
| 658 | //! It is possible to specify an environment variable fallback option for an arguments |
| 659 | //! so that its value is taken from the specified environment variable if not |
| 660 | //! given through the command-line: |
| 661 | //! |
| 662 | //! ``` |
| 663 | //! # use structopt::StructOpt; |
| 664 | //! |
| 665 | //! #[derive(StructOpt)] |
| 666 | //! struct Foo { |
| 667 | //! #[structopt(short, long, env = "PARAMETER_VALUE")] |
| 668 | //! parameter_value: String |
| 669 | //! } |
| 670 | //! ``` |
| 671 | //! |
| 672 | //! By default, values from the environment are shown in the help output (i.e. when invoking |
| 673 | //! `--help`): |
| 674 | //! |
| 675 | //! ```shell |
| 676 | //! $ cargo run -- --help |
| 677 | //! ... |
| 678 | //! OPTIONS: |
| 679 | //! -p, --parameter-value <parameter-value> [env: PARAMETER_VALUE=env_value] |
| 680 | //! ``` |
| 681 | //! |
| 682 | //! In some cases this may be undesirable, for example when being used for passing |
| 683 | //! credentials or secret tokens. In those cases you can use `hide_env_values` to avoid |
| 684 | //! having structopt emit the actual secret values: |
| 685 | //! ``` |
| 686 | //! # use structopt::StructOpt; |
| 687 | //! |
| 688 | //! #[derive(StructOpt)] |
| 689 | //! struct Foo { |
| 690 | //! #[structopt(long = "secret", env = "SECRET_VALUE", hide_env_values = true)] |
| 691 | //! secret_value: String |
| 692 | //! } |
| 693 | //! ``` |
| 694 | //! |
| 695 | //! ### Auto-deriving environment variables |
| 696 | //! |
| 697 | //! Environment variables tend to be called after the corresponding `struct`'s field, |
| 698 | //! as in example above. The field is `secret_value` and the env var is "SECRET_VALUE"; |
| 699 | //! the name is the same, except casing is different. |
| 700 | //! |
| 701 | //! It's pretty tedious and error-prone to type the same name twice, |
| 702 | //! so you can ask `structopt` to do that for you. |
| 703 | //! |
| 704 | //! ``` |
| 705 | //! # use structopt::StructOpt; |
| 706 | //! |
| 707 | //! #[derive(StructOpt)] |
| 708 | //! struct Foo { |
| 709 | //! #[structopt(long = "secret", env)] |
| 710 | //! secret_value: String |
| 711 | //! } |
| 712 | //! ``` |
| 713 | //! |
| 714 | //! It works just like `#[structopt(short/long)]`: if `env` is not set to some concrete |
| 715 | //! value the value will be derived from the field's name. This is controlled by |
| 716 | //! `#[structopt(rename_all_env)]`. |
| 717 | //! |
| 718 | //! `rename_all_env` works exactly as `rename_all` (including overriding) |
| 719 | //! except default casing is `SCREAMING_SNAKE_CASE` instead of `kebab-case`. |
| 720 | //! |
| 721 | //! ## Skipping fields |
| 722 | //! |
| 723 | //! Sometimes you may want to add a field to your `Opt` struct that is not |
| 724 | //! a command line option and `clap` should know nothing about it. You can ask |
| 725 | //! `structopt` to skip the field entirely via `#[structopt(skip = value)]` |
| 726 | //! (`value` must implement `Into<FieldType>`) |
| 727 | //! or `#[structopt(skip)]` if you want assign the field with `Default::default()` |
| 728 | //! (obviously, the field's type must implement `Default`). |
| 729 | //! |
| 730 | //! ``` |
| 731 | //! # use structopt::StructOpt; |
| 732 | //! #[derive(StructOpt)] |
| 733 | //! pub struct Opt { |
| 734 | //! #[structopt(long, short)] |
| 735 | //! number: u32, |
| 736 | //! |
| 737 | //! // these fields are to be assigned with Default::default() |
| 738 | //! |
| 739 | //! #[structopt(skip)] |
| 740 | //! k: String, |
| 741 | //! #[structopt(skip)] |
| 742 | //! v: Vec<u32>, |
| 743 | //! |
| 744 | //! // these fields get set explicitly |
| 745 | //! |
| 746 | //! #[structopt(skip = vec![1, 2, 3])] |
| 747 | //! k2: Vec<u32>, |
| 748 | //! #[structopt(skip = "cake")] // &str implements Into<String> |
| 749 | //! v2: String, |
| 750 | //! } |
| 751 | //! ``` |
| 752 | //! |
| 753 | //! ## Subcommands |
| 754 | //! |
| 755 | //! Some applications, especially large ones, split their functionality |
| 756 | //! through the use of "subcommands". Each of these act somewhat like a separate |
| 757 | //! command, but is part of the larger group. |
| 758 | //! One example is `git`, which has subcommands such as `add`, `commit`, |
| 759 | //! and `clone`, to mention just a few. |
| 760 | //! |
| 761 | //! `clap` has this functionality, and `structopt` supports it through enums: |
| 762 | //! |
| 763 | //! ``` |
| 764 | //! # use structopt::StructOpt; |
| 765 | //! |
| 766 | //! # use std::path::PathBuf; |
| 767 | //! #[derive(StructOpt)] |
| 768 | //! #[structopt(about = "the stupid content tracker")] |
| 769 | //! enum Git { |
| 770 | //! Add { |
| 771 | //! #[structopt(short)] |
| 772 | //! interactive: bool, |
| 773 | //! #[structopt(short)] |
| 774 | //! patch: bool, |
| 775 | //! #[structopt(parse(from_os_str))] |
| 776 | //! files: Vec<PathBuf> |
| 777 | //! }, |
| 778 | //! Fetch { |
| 779 | //! #[structopt(long)] |
| 780 | //! dry_run: bool, |
| 781 | //! #[structopt(long)] |
| 782 | //! all: bool, |
| 783 | //! repository: Option<String> |
| 784 | //! }, |
| 785 | //! Commit { |
| 786 | //! #[structopt(short)] |
| 787 | //! message: Option<String>, |
| 788 | //! #[structopt(short)] |
| 789 | //! all: bool |
| 790 | //! } |
| 791 | //! } |
| 792 | //! ``` |
| 793 | //! |
| 794 | //! Using `derive(StructOpt)` on an enum instead of a struct will produce |
| 795 | //! a `clap::App` that only takes subcommands. So `git add`, `git fetch`, |
| 796 | //! and `git commit` would be commands allowed for the above example. |
| 797 | //! |
| 798 | //! `structopt` also provides support for applications where certain flags |
| 799 | //! need to apply to all subcommands, as well as nested subcommands: |
| 800 | //! |
| 801 | //! ``` |
| 802 | //! # use structopt::StructOpt; |
| 803 | //! #[derive(StructOpt)] |
| 804 | //! struct MakeCookie { |
| 805 | //! #[structopt(name = "supervisor", default_value = "Puck", long = "supervisor")] |
| 806 | //! supervising_faerie: String, |
| 807 | //! /// The faerie tree this cookie is being made in. |
| 808 | //! tree: Option<String>, |
| 809 | //! #[structopt(subcommand)] // Note that we mark a field as a subcommand |
| 810 | //! cmd: Command |
| 811 | //! } |
| 812 | //! |
| 813 | //! #[derive(StructOpt)] |
| 814 | //! enum Command { |
| 815 | //! /// Pound acorns into flour for cookie dough. |
| 816 | //! Pound { |
| 817 | //! acorns: u32 |
| 818 | //! }, |
| 819 | //! /// Add magical sparkles -- the secret ingredient! |
| 820 | //! Sparkle { |
| 821 | //! #[structopt(short, parse(from_occurrences))] |
| 822 | //! magicality: u64, |
| 823 | //! #[structopt(short)] |
| 824 | //! color: String |
| 825 | //! }, |
| 826 | //! Finish(Finish), |
| 827 | //! } |
| 828 | //! |
| 829 | //! // Subcommand can also be externalized by using a 1-uple enum variant |
| 830 | //! #[derive(StructOpt)] |
| 831 | //! struct Finish { |
| 832 | //! #[structopt(short)] |
| 833 | //! time: u32, |
| 834 | //! #[structopt(subcommand)] // Note that we mark a field as a subcommand |
| 835 | //! finish_type: FinishType |
| 836 | //! } |
| 837 | //! |
| 838 | //! // subsubcommand! |
| 839 | //! #[derive(StructOpt)] |
| 840 | //! enum FinishType { |
| 841 | //! Glaze { |
| 842 | //! applications: u32 |
| 843 | //! }, |
| 844 | //! Powder { |
| 845 | //! flavor: String, |
| 846 | //! dips: u32 |
| 847 | //! } |
| 848 | //! } |
| 849 | //! ``` |
| 850 | //! |
| 851 | //! Marking a field with `structopt(subcommand)` will add the subcommands of the |
| 852 | //! designated enum to the current `clap::App`. The designated enum *must* also |
| 853 | //! be derived `StructOpt`. So the above example would take the following |
| 854 | //! commands: |
| 855 | //! |
| 856 | //! + `make-cookie pound 50` |
| 857 | //! + `make-cookie sparkle -mmm --color "green"` |
| 858 | //! + `make-cookie finish 130 glaze 3` |
| 859 | //! |
| 860 | //! ### Optional subcommands |
| 861 | //! |
| 862 | //! Subcommands may be optional: |
| 863 | //! |
| 864 | //! ``` |
| 865 | //! # use structopt::StructOpt; |
| 866 | //! #[derive(StructOpt)] |
| 867 | //! struct Foo { |
| 868 | //! file: String, |
| 869 | //! #[structopt(subcommand)] |
| 870 | //! cmd: Option<Command> |
| 871 | //! } |
| 872 | //! |
| 873 | //! #[derive(StructOpt)] |
| 874 | //! enum Command { |
| 875 | //! Bar, |
| 876 | //! Baz, |
| 877 | //! Quux |
| 878 | //! } |
| 879 | //! ``` |
| 880 | //! |
| 881 | //! ### External subcommands |
| 882 | //! |
| 883 | //! Sometimes you want to support not only the set of well-known subcommands |
| 884 | //! but you also want to allow other, user-driven subcommands. `clap` supports |
| 885 | //! this via [`AppSettings::AllowExternalSubcommands`]. |
| 886 | //! |
| 887 | //! `structopt` provides it's own dedicated syntax for that: |
| 888 | //! |
| 889 | //! ``` |
| 890 | //! # use structopt::StructOpt; |
| 891 | //! #[derive(Debug, PartialEq, StructOpt)] |
| 892 | //! struct Opt { |
| 893 | //! #[structopt(subcommand)] |
| 894 | //! sub: Subcommands, |
| 895 | //! } |
| 896 | //! |
| 897 | //! #[derive(Debug, PartialEq, StructOpt)] |
| 898 | //! enum Subcommands { |
| 899 | //! // normal subcommand |
| 900 | //! Add, |
| 901 | //! |
| 902 | //! // `external_subcommand` tells structopt to put |
| 903 | //! // all the extra arguments into this Vec |
| 904 | //! #[structopt(external_subcommand)] |
| 905 | //! Other(Vec<String>), |
| 906 | //! } |
| 907 | //! |
| 908 | //! // normal subcommand |
| 909 | //! assert_eq!( |
| 910 | //! Opt::from_iter(&["test", "add"]), |
| 911 | //! Opt { |
| 912 | //! sub: Subcommands::Add |
| 913 | //! } |
| 914 | //! ); |
| 915 | //! |
| 916 | //! assert_eq!( |
| 917 | //! Opt::from_iter(&["test", "git", "status"]), |
| 918 | //! Opt { |
| 919 | //! sub: Subcommands::Other(vec!["git".into(), "status".into()]) |
| 920 | //! } |
| 921 | //! ); |
| 922 | //! |
| 923 | //! // Please note that if you'd wanted to allow "no subcommands at all" case |
| 924 | //! // you should have used `sub: Option<Subcommands>` above |
| 925 | //! assert!(Opt::from_iter_safe(&["test"]).is_err()); |
| 926 | //! ``` |
| 927 | //! |
| 928 | //! In other words, you just add an extra tuple variant marked with |
| 929 | //! `#[structopt(subcommand)]`, and its type must be either |
| 930 | //! `Vec<String>` or `Vec<OsString>`. `structopt` will detect `String` in this context |
| 931 | //! and use appropriate `clap` API. |
| 932 | //! |
| 933 | //! [`AppSettings::AllowExternalSubcommands`]: https://docs.rs/clap/2.32.0/clap/enum.AppSettings.html#variant.AllowExternalSubcommands |
| 934 | //! |
| 935 | //! ### Flattening subcommands |
| 936 | //! |
| 937 | //! It is also possible to combine multiple enums of subcommands into one. |
| 938 | //! All the subcommands will be on the same level. |
| 939 | //! |
| 940 | //! ``` |
| 941 | //! # use structopt::StructOpt; |
| 942 | //! #[derive(StructOpt)] |
| 943 | //! enum BaseCli { |
| 944 | //! Ghost10 { |
| 945 | //! arg1: i32, |
| 946 | //! } |
| 947 | //! } |
| 948 | //! |
| 949 | //! #[derive(StructOpt)] |
| 950 | //! enum Opt { |
| 951 | //! #[structopt(flatten)] |
| 952 | //! BaseCli(BaseCli), |
| 953 | //! Dex { |
| 954 | //! arg2: i32, |
| 955 | //! } |
| 956 | //! } |
| 957 | //! ``` |
| 958 | //! |
| 959 | //! ```shell |
| 960 | //! cli ghost10 42 |
| 961 | //! cli dex 42 |
| 962 | //! ``` |
| 963 | //! |
| 964 | //! ## Flattening |
| 965 | //! |
| 966 | //! It can sometimes be useful to group related arguments in a substruct, |
| 967 | //! while keeping the command-line interface flat. In these cases you can mark |
| 968 | //! a field as `flatten` and give it another type that derives `StructOpt`: |
| 969 | //! |
| 970 | //! ``` |
| 971 | //! # use structopt::StructOpt; |
| 972 | //! #[derive(StructOpt)] |
| 973 | //! struct Cmdline { |
| 974 | //! /// switch on verbosity |
| 975 | //! #[structopt(short)] |
| 976 | //! verbose: bool, |
| 977 | //! #[structopt(flatten)] |
| 978 | //! daemon_opts: DaemonOpts, |
| 979 | //! } |
| 980 | //! |
| 981 | //! #[derive(StructOpt)] |
| 982 | //! struct DaemonOpts { |
| 983 | //! /// daemon user |
| 984 | //! #[structopt(short)] |
| 985 | //! user: String, |
| 986 | //! /// daemon group |
| 987 | //! #[structopt(short)] |
| 988 | //! group: String, |
| 989 | //! } |
| 990 | //! ``` |
| 991 | //! |
| 992 | //! In this example, the derived `Cmdline` parser will support the options `-v`, |
| 993 | //! `-u` and `-g`. |
| 994 | //! |
| 995 | //! This feature also makes it possible to define a `StructOpt` struct in a |
| 996 | //! library, parse the corresponding arguments in the main argument parser, and |
| 997 | //! pass off this struct to a handler provided by that library. |
| 998 | //! |
| 999 | //! ## Custom string parsers |
| 1000 | //! |
| 1001 | //! If the field type does not have a `FromStr` implementation, or you would |
| 1002 | //! like to provide a custom parsing scheme other than `FromStr`, you may |
| 1003 | //! provide a custom string parser using `parse(...)` like this: |
| 1004 | //! |
| 1005 | //! ``` |
| 1006 | //! # use structopt::StructOpt; |
| 1007 | //! use std::num::ParseIntError; |
| 1008 | //! use std::path::PathBuf; |
| 1009 | //! |
| 1010 | //! fn parse_hex(src: &str) -> Result<u32, ParseIntError> { |
| 1011 | //! u32::from_str_radix(src, 16) |
| 1012 | //! } |
| 1013 | //! |
| 1014 | //! #[derive(StructOpt)] |
| 1015 | //! struct HexReader { |
| 1016 | //! #[structopt(short, parse(try_from_str = parse_hex))] |
| 1017 | //! number: u32, |
| 1018 | //! #[structopt(short, parse(from_os_str))] |
| 1019 | //! output: PathBuf, |
| 1020 | //! } |
| 1021 | //! ``` |
| 1022 | //! |
| 1023 | //! There are five kinds of custom parsers: |
| 1024 | //! |
| 1025 | //! | Kind | Signature | Default | |
| 1026 | //! |-------------------|---------------------------------------|---------------------------------| |
| 1027 | //! | `from_str` | `fn(&str) -> T` | `::std::convert::From::from` | |
| 1028 | //! | `try_from_str` | `fn(&str) -> Result<T, E>` | `::std::str::FromStr::from_str` | |
| 1029 | //! | `from_os_str` | `fn(&OsStr) -> T` | `::std::convert::From::from` | |
| 1030 | //! | `try_from_os_str` | `fn(&OsStr) -> Result<T, OsString>` | (no default function) | |
| 1031 | //! | `from_occurrences`| `fn(u64) -> T` | `value as T` | |
| 1032 | //! | `from_flag` | `fn(bool) -> T` | `::std::convert::From::from` | |
| 1033 | //! |
| 1034 | //! The `from_occurrences` parser is special. Using `parse(from_occurrences)` |
| 1035 | //! results in the _number of flags occurrences_ being stored in the relevant |
| 1036 | //! field or being passed to the supplied function. In other words, it converts |
| 1037 | //! something like `-vvv` to `3`. This is equivalent to |
| 1038 | //! `.takes_value(false).multiple(true)`. Note that the default parser can only |
| 1039 | //! be used with fields of integer types (`u8`, `usize`, `i64`, etc.). |
| 1040 | //! |
| 1041 | //! The `from_flag` parser is also special. Using `parse(from_flag)` or |
| 1042 | //! `parse(from_flag = some_func)` will result in the field being treated as a |
| 1043 | //! flag even if it does not have type `bool`. |
| 1044 | //! |
| 1045 | //! When supplying a custom string parser, `bool` will not be treated specially: |
| 1046 | //! |
| 1047 | //! Type | Effect | Added method call to `clap::Arg` |
| 1048 | //! ------------|-------------------|-------------------------------------- |
| 1049 | //! `Option<T>` | optional argument | `.takes_value(true).multiple(false)` |
| 1050 | //! `Vec<T>` | list of arguments | `.takes_value(true).multiple(true)` |
| 1051 | //! `T` | required argument | `.takes_value(true).multiple(false).required(!has_default)` |
| 1052 | //! |
| 1053 | //! In the `try_from_*` variants, the function will run twice on valid input: |
| 1054 | //! once to validate, and once to parse. Hence, make sure the function is |
| 1055 | //! side-effect-free. |
| 1056 | |
| 1057 | // those mains are for a reason |
| 1058 | #![allow(clippy::needless_doctest_main)] |
| 1059 | |
| 1060 | #[doc(hidden)] |
| 1061 | pub use structopt_derive::*; |
| 1062 | |
| 1063 | use std::ffi::OsString; |
| 1064 | |
| 1065 | /// Re-exports |
| 1066 | pub use clap; |
Haibo Huang | e7bfadf | 2020-09-23 21:23:42 -0700 | [diff] [blame^] | 1067 | #[cfg(feature = "paw")] |
| 1068 | pub use paw_dep as paw; |
Matthew Maurer | 32e7669 | 2020-06-02 11:15:15 -0700 | [diff] [blame] | 1069 | |
| 1070 | /// **This is NOT PUBLIC API**. |
| 1071 | #[doc(hidden)] |
| 1072 | pub use lazy_static; |
| 1073 | |
| 1074 | /// A struct that is converted from command line arguments. |
| 1075 | pub trait StructOpt { |
| 1076 | /// Returns the corresponding `clap::App`. |
| 1077 | fn clap<'a, 'b>() -> clap::App<'a, 'b>; |
| 1078 | |
| 1079 | /// Creates the struct from `clap::ArgMatches`. It cannot fail |
| 1080 | /// with a parameter generated by `clap` by construction. |
| 1081 | fn from_clap(matches: &clap::ArgMatches<'_>) -> Self; |
| 1082 | |
| 1083 | /// Gets the struct from the command line arguments. Print the |
| 1084 | /// error message and quit the program in case of failure. |
| 1085 | fn from_args() -> Self |
| 1086 | where |
| 1087 | Self: Sized, |
| 1088 | { |
| 1089 | Self::from_clap(&Self::clap().get_matches()) |
| 1090 | } |
| 1091 | |
| 1092 | /// Gets the struct from any iterator such as a `Vec` of your making. |
| 1093 | /// Print the error message and quit the program in case of failure. |
| 1094 | /// |
| 1095 | /// **NOTE**: The first argument will be parsed as the binary name unless |
| 1096 | /// [`AppSettings::NoBinaryName`] has been used. |
| 1097 | /// |
| 1098 | /// [`AppSettings::NoBinaryName`]: https://docs.rs/clap/2.33.0/clap/enum.AppSettings.html#variant.NoBinaryName |
| 1099 | fn from_iter<I>(iter: I) -> Self |
| 1100 | where |
| 1101 | Self: Sized, |
| 1102 | I: IntoIterator, |
| 1103 | I::Item: Into<OsString> + Clone, |
| 1104 | { |
| 1105 | Self::from_clap(&Self::clap().get_matches_from(iter)) |
| 1106 | } |
| 1107 | |
| 1108 | /// Gets the struct from any iterator such as a `Vec` of your making. |
| 1109 | /// |
| 1110 | /// Returns a `clap::Error` in case of failure. This does *not* exit in the |
| 1111 | /// case of `--help` or `--version`, to achieve the same behavior as |
| 1112 | /// `from_iter()` you must call `.exit()` on the error value. |
| 1113 | /// |
| 1114 | /// **NOTE**: The first argument will be parsed as the binary name unless |
| 1115 | /// [`AppSettings::NoBinaryName`] has been used. |
| 1116 | /// |
| 1117 | /// [`AppSettings::NoBinaryName`]: https://docs.rs/clap/2.33.0/clap/enum.AppSettings.html#variant.NoBinaryName |
| 1118 | fn from_iter_safe<I>(iter: I) -> Result<Self, clap::Error> |
| 1119 | where |
| 1120 | Self: Sized, |
| 1121 | I: IntoIterator, |
| 1122 | I::Item: Into<OsString> + Clone, |
| 1123 | { |
| 1124 | Ok(Self::from_clap(&Self::clap().get_matches_from_safe(iter)?)) |
| 1125 | } |
| 1126 | } |
| 1127 | |
| 1128 | /// This trait is NOT API. **SUBJECT TO CHANGE WITHOUT NOTICE!**. |
| 1129 | #[doc(hidden)] |
| 1130 | pub trait StructOptInternal: StructOpt { |
| 1131 | fn augment_clap<'a, 'b>(app: clap::App<'a, 'b>) -> clap::App<'a, 'b> { |
| 1132 | app |
| 1133 | } |
| 1134 | |
| 1135 | fn is_subcommand() -> bool { |
| 1136 | false |
| 1137 | } |
| 1138 | |
| 1139 | fn from_subcommand<'a, 'b>(_sub: (&'b str, Option<&'b clap::ArgMatches<'a>>)) -> Option<Self> |
| 1140 | where |
| 1141 | Self: std::marker::Sized, |
| 1142 | { |
| 1143 | None |
| 1144 | } |
| 1145 | } |
| 1146 | |
| 1147 | impl<T: StructOpt> StructOpt for Box<T> { |
| 1148 | fn clap<'a, 'b>() -> clap::App<'a, 'b> { |
| 1149 | <T as StructOpt>::clap() |
| 1150 | } |
| 1151 | |
| 1152 | fn from_clap(matches: &clap::ArgMatches<'_>) -> Self { |
| 1153 | Box::new(<T as StructOpt>::from_clap(matches)) |
| 1154 | } |
| 1155 | } |
| 1156 | |
| 1157 | impl<T: StructOptInternal> StructOptInternal for Box<T> { |
| 1158 | #[doc(hidden)] |
| 1159 | fn is_subcommand() -> bool { |
| 1160 | <T as StructOptInternal>::is_subcommand() |
| 1161 | } |
| 1162 | |
| 1163 | #[doc(hidden)] |
| 1164 | fn from_subcommand<'a, 'b>(sub: (&'b str, Option<&'b clap::ArgMatches<'a>>)) -> Option<Self> { |
| 1165 | <T as StructOptInternal>::from_subcommand(sub).map(Box::new) |
| 1166 | } |
| 1167 | |
| 1168 | #[doc(hidden)] |
| 1169 | fn augment_clap<'a, 'b>(app: clap::App<'a, 'b>) -> clap::App<'a, 'b> { |
| 1170 | <T as StructOptInternal>::augment_clap(app) |
| 1171 | } |
| 1172 | } |