1# Derive Reference 2 31. [Overview](#overview) 42. [Raw Attributes](#raw-attributes) 53. [Magic Attributes](#magic-attributes) 6 1. [App Attributes](#app-attributes) 7 2. [Arg Attributes](#arg-attributes) 8 3. [Arg Types](#arg-types) 9 4. [Arg Enum Attributes](#arg-enum-attributes) 10 5. [Possible Value Attributes](#possible-value-attributes) 11 6. [Doc Comments](#doc-comments) 12 13## Overview 14 15To derive `clap` types, you need to enable the `derive` feature flag. 16 17See [demo.rs](../demo.rs) and [demo.md](../demo.md) for a brief example. 18 19Let's start by breaking down what can go where: 20```rust 21use clap::{Parser, Args, Subcommand, ArgEnum}; 22 23/// Doc comment 24#[derive(Parser)] 25#[clap(APP ATTRIBUTE)] 26struct Cli { 27 /// Doc comment 28 #[clap(ARG ATTRIBUTE)] 29 field: Type, 30 31 #[clap(flatten)] 32 delegate: Struct, 33 34 #[clap(subcommand)] 35 command: Command, 36} 37 38/// Doc comment 39#[derive(Args)] 40#[clap(PARENT APP ATTRIBUTE)] 41struct Struct { 42 /// Doc comment 43 #[clap(ARG ATTRIBUTE)] 44 field: Type, 45} 46 47/// Doc comment 48#[derive(Subcommand)] 49#[clap(PARENT APP ATTRIBUTE)] 50enum Command { 51 /// Doc comment 52 #[clap(APP ATTRIBUTE)] 53 Variant1(Struct), 54 55 /// Doc comment 56 #[clap(APP ATTRIBUTE)] 57 Variant2 { 58 /// Doc comment 59 #[clap(ARG ATTRIBUTE)] 60 field: Type, 61 } 62} 63 64/// Doc comment 65#[derive(ArgEnum)] 66#[clap(ARG ENUM ATTRIBUTE)] 67enum Mode { 68 /// Doc comment 69 #[clap(POSSIBLE VALUE ATTRIBUTE)] 70 Variant1, 71} 72 73fn main() { 74 let cli = Cli::parse(); 75} 76``` 77 78- `Parser` parses arguments into a `struct` (arguments) or `enum` (subcommands). 79- `Args` allows defining a set of re-usable arguments that get merged into their parent container. 80- `Subcommand` defines available subcommands. 81- `ArgEnum` allows parsing a value directly into an `enum`, erroring on unsupported values. 82 83See also the [tutorial](../tutorial_derive/README.md) and [examples](../README.md). 84 85## Raw Attributes 86 87**Raw attributes** are forwarded directly to the underlying `clap` builder. Any 88`App`, `Arg`, or `PossibleValue` method can be used as an attribute. 89 90Raw attributes come in two different syntaxes: 91```rust 92#[clap( 93 global = true, // name = arg form, neat for one-arg methods 94 required_if_eq("out", "file") // name(arg1, arg2, ...) form. 95)] 96``` 97 98- `method = arg` can only be used for methods which take only one argument. 99- `method(arg1, arg2)` can be used with any method. 100 101As long as `method_name` is not one of the magical methods - it will be 102translated into a mere method call. 103 104## Magic Attributes 105 106**Magic attributes** have post-processing done to them, whether that is 107- Providing of defaults 108- Special behavior is triggered off of it 109 110### App Attributes 111 112These correspond to a `clap::App` which is used for both top-level parsers and 113when defining subcommands. 114 115In addition to the raw attributes, the following magic attributes are supported: 116- `name = <expr>`: `clap::App::name` 117 - When not present: [crate `name`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-name-field) (`Parser` container), variant name (`Subcommand` variant) 118- `version [= <expr>]`: `clap::App::version` 119 - When not present: no version set 120 - Without `<expr>`: defaults to [crate `version`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-version-field) 121- `author [= <expr>]`: `clap::App::author` 122 - When not present: no author set 123 - Without `<expr>`: defaults to [crate `authors`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-authors-field) 124- `about [= <expr>]`: `clap::App::about` 125 - When not present: [Doc comment summary](#doc-comments) 126 - Without `<expr>`: [crate `description`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-description-field) (`Parser` container) 127 - **TIP:** When a doc comment is also present, you most likely want to add 128 `#[clap(long_about = None)]` to clear the doc comment so only `about` 129 gets shown with both `-h` and `--help`. 130- `long_about = <expr>`: `clap::App::long_about` 131 - When not present: [Doc comment](#doc-comments) if there is a blank line, else nothing 132- `verbatim_doc_comment`: Minimizes pre-processing when converting doc comments to `about` / `long_about` 133- `help_heading`: `clap::App::help_heading` 134 - When `flatten`ing `Args`, this is scoped to just the args in this struct and any struct `flatten`ed into it 135- `rename_all = <expr>`: Override default field / variant name case conversion for `App::name` / `Arg::name` 136 - When not present: `kebab-case` 137 - Available values: `camelCase`, `kebab-case`, `PascalCase`, `SCREAMING_SNAKE_CASE`, `snake_case`, `lower`, `UPPER`, `verbatim` 138- `rename_all_env = <expr>`: Override default field name case conversion for env variables for `clap::Arg::env` 139 - When not present: `SCREAMING_SNAKE_CASE` 140 - Available values: `camelCase`, `kebab-case`, `PascalCase`, `SCREAMING_SNAKE_CASE`, `snake_case`, `lower`, `UPPER`, `verbatim` 141 142And for `Subcommand` variants: 143- `skip`: Ignore this variant 144- `flatten`: Delegates to the variant for more subcommands (must implement `Subcommand`) 145- `subcommand`: Nest subcommands under the current set of subcommands (must implement `Subcommand`) 146- `external_subcommand`: `clap::AppSettings::AllowExternalSubcommand` 147 - Variant must be either `Variant(Vec<String>)` or `Variant(Vec<OsString>)` 148 149### Arg Attributes 150 151These correspond to a `clap::Arg`. 152 153In addition to the raw attributes, the following magic attributes are supported: 154- `name = <expr>`: `clap::Arg::new` 155 - When not present: case-converted field name is used 156- `help = <expr>`: `clap::Arg::help` 157 - When not present: [Doc comment summary](#doc-comments) 158- `long_help = <expr>`: `clap::Arg::long_help` 159 - When not present: [Doc comment](#doc-comments) if there is a blank line, else nothing 160- `verbatim_doc_comment`: Minimizes pre-processing when converting doc comments to `help` / `long_help` 161- `short [= <char>]`: `clap::Arg::short` 162 - When not present: no short set 163 - Without `<char>`: defaults to first character in the case-converted field name 164- `long [= <str>]`: `clap::Arg::long` 165 - When not present: no long set 166 - Without `<str>`: defaults to the case-converted field name 167- `env [= <str>]`: `clap::Arg::env` 168 - When not present: no env set 169 - Without `<str>`: defaults to the case-converted field name 170- `flatten`: Delegates to the field for more arguments (must implement `Args`) 171 - Only `help_heading` can be used with `flatten`. See 172 [clap-rs/clap#3269](https://github.com/clap-rs/clap/issues/3269) for why 173 arg attributes are not generally supported. 174 - **Tip:** Though we do apply a flattened `Args`'s Parent App Attributes, this 175 makes reuse harder. Generally prefer putting the app attributes on the `Parser` 176 or on the flattened field. 177- `subcommand`: Delegates definition of subcommands to the field (must implement `Subcommand`) 178 - When `Option<T>`, the subcommand becomes optional 179- `from_global`: Read a `clap::Arg::global` argument (raw attribute), regardless of what subcommand you are in 180- `parse(<kind> [= <function>])` `clap::Arg::validator` 181- `arg_enum`: Parse the value using the `ArgEnum` trait 182- `skip [= <expr>]`: Ignore this field, filling in with `<expr>` 183 - Without `<expr>`: fills the field with `Default::default()` 184- `default_value = <str>`: `clap::Arg::default_value` and `clap::Arg::required(false)` 185- `default_value_t [= <expr>]`: `clap::Arg::default_value` and `clap::Arg::required(false)` 186 - Requires `std::fmt::Display` or `#[clap(arg_enum)]` 187 - Without `<expr>`, relies on `Default::default()` 188- `default_value_os_t [= <expr>]`: `clap::Arg::default_value_os` and `clap::Arg::required(false)` 189 - Requires `std::convert::Into<OsString>` or `#[clap(arg_enum)]` 190 - Without `<expr>`, relies on `Default::default()` 191 192### Arg Types 193 194`clap` assumes some intent based on the type used: 195 196| Type | Effect | Implies | 197|---------------------|--------------------------------------|------------------------------------------------------------------| 198| `bool` | flag | `#[clap(parse(from_flag))]` | 199| `Option<T>` | optional argument | `.takes_value(true).required(false)` | 200| `Option<Option<T>>` | optional value for optional argument | `.takes_value(true).required(false).min_values(0).max_values(1)` | 201| `T` | required argument | `.takes_value(true).required(!has_default)` | 202| `Vec<T>` | `0..` occurrences of argument | `.takes_value(true).required(false).multiple_occurrences(true)` | 203| `Option<Vec<T>>` | `0..` occurrences of argument | `.takes_value(true).required(false).multiple_occurrences(true)` | 204 205Notes: 206- For custom type behavior, you can override the implied attributes/settings and/or set additional ones 207 - For example, see [custom-bool](./custom-bool.md) 208- `Option<Vec<T>>` will be `None` instead of `vec![]` if no arguments are provided. 209 - This gives the user some flexibility in designing their argument, like with `min_values(0)` 210 211You can then support your custom type with `#[clap(parse(<kind> [= <function>]))]`: 212 213| `<kind>` | Signature | Default `<function>` | 214|--------------------------|---------------------------------------|---------------------------------| 215| `from_str` | `fn(&str) -> T` | `::std::convert::From::from` | 216| `try_from_str` (default) | `fn(&str) -> Result<T, E>` | `::std::str::FromStr::from_str` | 217| `from_os_str` | `fn(&OsStr) -> T` | `::std::convert::From::from` | 218| `try_from_os_str` | `fn(&OsStr) -> Result<T, OsString>` | (no default function) | 219| `from_occurrences` | `fn(u64) -> T` | `value as T` | 220| `from_flag` | `fn(bool) -> T` | `::std::convert::From::from` | 221 222Notes: 223- `from_os_str`: 224 - Implies `arg.takes_value(true).allow_invalid_utf8(true)` 225- `try_from_os_str`: 226 - Implies `arg.takes_value(true).allow_invalid_utf8(true)` 227- `from_occurrences`: 228 - Implies `arg.takes_value(false).multiple_occurrences(true)` 229 - Reads from `clap::ArgMatches::occurrences_of` rather than a `value_of` function 230 - Note: operations on values, like `default_value`, are unlikely to do what you want 231- `from_flag` 232 - Implies `arg.takes_value(false)` 233 - Reads from `clap::ArgMatches::is_present` rather than a `value_of` function 234 - Note: operations on values, like `default_value`, are unlikely to do what you want 235 236**Warning:** 237- To support non-UTF8 paths, you must use `parse(from_os_str)`, otherwise 238 `clap` will use `clap::ArgMatches::value_of` with `PathBuf::FromStr`. 239 240### Arg Enum Attributes 241 242- `rename_all = <expr>`: Override default field / variant name case conversion for `PossibleValue::new` 243 - When not present: `kebab-case` 244 - Available values: `camelCase`, `kebab-case`, `PascalCase`, `SCREAMING_SNAKE_CASE`, `snake_case`, `lower`, `UPPER`, `verbatim` 245 246### Possible Value Attributes 247 248These correspond to a `clap::PossibleValue`. 249 250- `name = <expr>`: `clap::PossibleValue::new` 251 - When not present: case-converted field name is used 252- `help = <expr>`: `clap::PossibleValue::help` 253 - When not present: [Doc comment summary](#doc-comments) 254 255### Doc Comments 256 257In clap, help messages for the whole binary can be specified 258via [`App::about`] and [`App::long_about`] while help messages 259for individual arguments can be specified via [`Arg::help`] and [`Arg::long_help`]". 260 261`long_*` variants are used when user calls the program with 262`--help` and "short" variants are used with `-h` flag. 263 264```rust 265# use clap::Parser; 266 267#[derive(Parser)] 268#[clap(about = "I am a program and I work, just pass `-h`", long_about = None)] 269struct Foo { 270 #[clap(short, help = "Pass `-h` and you'll see me!")] 271 bar: String, 272} 273``` 274 275For convenience, doc comments can be used instead of raw methods 276(this example works exactly like the one above): 277 278```rust 279# use clap::Parser; 280 281#[derive(Parser)] 282/// I am a program and I work, just pass `-h` 283struct Foo { 284 /// Pass `-h` and you'll see me! 285 bar: String, 286} 287``` 288 289**NOTE:** Attributes have priority over doc comments! 290 291**Top level doc comments always generate `App::about/long_about` calls!** 292If you really want to use the `App::about/long_about` methods (you likely don't), 293use the `about` / `long_about` attributes to override the calls generated from 294the doc comment. To clear `long_about`, you can use 295`#[clap(long_about = None)]`. 296 297**TIP:** Set `#![deny(missing_docs)]` to catch missing `--help` documentation at compile time. 298 299#### Pre-processing 300 301```rust 302# use clap::Parser; 303#[derive(Parser)] 304/// Hi there, I'm Robo! 305/// 306/// I like beeping, stumbling, eating your electricity, 307/// and making records of you singing in a shower. 308/// Pay up, or I'll upload it to youtube! 309struct Robo { 310 /// Call my brother SkyNet. 311 /// 312 /// I am artificial superintelligence. I won't rest 313 /// until I'll have destroyed humanity. Enjoy your 314 /// pathetic existence, you mere mortals. 315 #[clap(long)] 316 kill_all_humans: bool, 317} 318``` 319 320A doc comment consists of three parts: 321- Short summary 322- A blank line (whitespace only) 323- Detailed description, all the rest 324 325The summary corresponds with `App::about` / `Arg::help`. When a blank line is 326present, the whole doc comment will be passed to `App::long_about` / 327`Arg::long_help`. Or in other words, a doc may result in just a `App::about` / 328`Arg::help` or `App::about` / `Arg::help` and `App::long_about` / 329`Arg::long_help` 330 331In addition, when `verbatim_doc_comment` is not present, `clap` applies some preprocessing, including: 332 333- Strip leading and trailing whitespace from every line, if present. 334 335- Strip leading and trailing blank lines, if present. 336 337- Interpret each group of non-empty lines as a word-wrapped paragraph. 338 339 We replace newlines within paragraphs with spaces to allow the output 340 to be re-wrapped to the terminal width. 341 342- Strip any excess blank lines so that there is exactly one per paragraph break. 343 344- If the first paragraph ends in exactly one period, 345 remove the trailing period (i.e. strip trailing periods but not trailing ellipses). 346 347Sometimes you don't want this preprocessing to apply, for example the comment contains 348some ASCII art or markdown tables, you would need to preserve LFs along with 349blank lines and the leading/trailing whitespace. When you pass use the 350`verbatim_doc_comment` magic attribute, you preserve 351them. 352 353**Note:** Keep in mind that `verbatim_doc_comment` will *still* 354- Remove one leading space from each line, even if this attribute is present, 355 to allow for a space between `///` and the content. 356- Remove leading and trailing blank lines 357