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