]> git.proxmox.com Git - rustc.git/blob - vendor/clap/examples/derive_ref/README.md
New upstream version 1.64.0+dfsg1
[rustc.git] / vendor / clap / examples / derive_ref / README.md
1 # Derive Reference
2
3 1. [Overview](#overview)
4 2. [Attributes](#attributes)
5 1. [Terminology](#terminology)
6 2. [Command Attributes](#command-attributes)
7 3. [Arg Attributes](#arg-attributes)
8 4. [Arg Enum Attributes](#arg-enum-attributes)
9 5. [Possible Value Attributes](#possible-value-attributes)
10 3. [Arg Types](#arg-types)
11 4. [Doc Comments](#doc-comments)
12 5. [Tips](#tips)
13 6. [Mixing Builder and Derive APIS](#mixing-builder-and-derive-apis)
14
15 ## Overview
16
17 To derive `clap` types, you need to enable the `derive` feature flag.
18
19 See [demo.rs](../demo.rs) and [demo.md](../demo.md) for a brief example.
20
21 Let's start by breaking down the anatomy of the derive attributes:
22 ```rust
23 use clap::{Parser, Args, Subcommand, ValueEnum};
24
25 /// Doc comment
26 #[derive(Parser)]
27 #[clap(APP ATTRIBUTE)]
28 struct Cli {
29 /// Doc comment
30 #[clap(ARG ATTRIBUTE)]
31 field: UserType,
32
33 #[clap(value_enum, ARG ATTRIBUTE...)]
34 field: EnumValues,
35
36 #[clap(flatten)]
37 delegate: Struct,
38
39 #[clap(subcommand)]
40 command: Command,
41 }
42
43 /// Doc comment
44 #[derive(Args)]
45 #[clap(PARENT APP ATTRIBUTE)]
46 struct Struct {
47 /// Doc comment
48 #[clap(ARG ATTRIBUTE)]
49 field: UserType,
50 }
51
52 /// Doc comment
53 #[derive(Subcommand)]
54 #[clap(PARENT APP ATTRIBUTE)]
55 enum Command {
56 /// Doc comment
57 #[clap(APP ATTRIBUTE)]
58 Variant1(Struct),
59
60 /// Doc comment
61 #[clap(APP ATTRIBUTE)]
62 Variant2 {
63 /// Doc comment
64 #[clap(ARG ATTRIBUTE)]
65 field: UserType,
66 }
67 }
68
69 /// Doc comment
70 #[derive(ValueEnum)]
71 #[clap(ARG ENUM ATTRIBUTE)]
72 enum EnumValues {
73 /// Doc comment
74 #[clap(POSSIBLE VALUE ATTRIBUTE)]
75 Variant1,
76 }
77
78 fn main() {
79 let cli = Cli::parse();
80 }
81 ```
82
83 - `Parser` parses arguments into a `struct` (arguments) or `enum` (subcommands).
84 - `Args` allows defining a set of re-usable arguments that get merged into their parent container.
85 - `Subcommand` defines available subcommands.
86 - Subcommand arguments can be defined in a struct-variant or automatically flattened with a tuple-variant.
87 - `ValueEnum` allows parsing a value directly into an `enum`, erroring on unsupported values.
88 - The derive doesn't work on enums that contain non-unit variants, unless they are skipped
89
90 See also the [tutorial](../tutorial_derive/README.md) and [examples](../README.md).
91
92 ## Attributes
93
94 ### Terminology
95
96 **Raw attributes** are forwarded directly to the underlying `clap` builder. Any
97 `Command`, `Arg`, or `PossibleValue` method can be used as an attribute.
98
99 Raw attributes come in two different syntaxes:
100 ```rust
101 #[clap(
102 global = true, // name = arg form, neat for one-arg methods
103 required_if_eq("out", "file") // name(arg1, arg2, ...) form.
104 )]
105 ```
106
107 - `method = arg` can only be used for methods which take only one argument.
108 - `method(arg1, arg2)` can be used with any method.
109
110 As long as `method_name` is not one of the magical methods - it will be
111 translated into a mere method call.
112
113 **Magic attributes** have post-processing done to them, whether that is
114 - Providing of defaults
115 - Special behavior is triggered off of it
116
117 Magic attributes are more constrained in the syntax they support, usually just
118 `<attr> = <value>` though some use `<attr>(<value>)` instead. See the specific
119 magic attributes documentation for details. This allows users to access the
120 raw behavior of an attribute via `<attr>(<value>)` syntax.
121
122 **NOTE:** Some attributes are inferred from [Arg Types](#arg-types) and [Doc
123 Comments](#doc-comments). Explicit attributes take precedence over inferred
124 attributes.
125
126 ### Command Attributes
127
128 These correspond to a `clap::Command` which is used for both top-level parsers and
129 when defining subcommands.
130
131 **Raw attributes:** Any [`Command` method](https://docs.rs/clap/latest/clap/type.Command.html) can also be used as an attribute, see [Terminology](#terminology) for syntax.
132 - e.g. `#[clap(arg_required_else_help(true))]` would translate to `cmd.arg_required_else_help(true)`
133
134 **Magic attributes:**
135 - `name = <expr>`: `clap::Command::name`
136 - When not present: [crate `name`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-name-field) (`Parser` container), variant name (`Subcommand` variant)
137 - `version [= <expr>]`: `clap::Command::version`
138 - When not present: no version set
139 - Without `<expr>`: defaults to [crate `version`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-version-field)
140 - `author [= <expr>]`: `clap::Command::author`
141 - When not present: no author set
142 - Without `<expr>`: defaults to [crate `authors`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-authors-field)
143 - `about [= <expr>]`: `clap::Command::about`
144 - When not present: [Doc comment summary](#doc-comments)
145 - Without `<expr>`: [crate `description`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-description-field) (`Parser` container)
146 - **TIP:** When a doc comment is also present, you most likely want to add
147 `#[clap(long_about = None)]` to clear the doc comment so only `about`
148 gets shown with both `-h` and `--help`.
149 - `long_about = <expr>`: `clap::Command::long_about`
150 - When not present: [Doc comment](#doc-comments) if there is a blank line, else nothing
151 - `verbatim_doc_comment`: Minimizes pre-processing when converting doc comments to `about` / `long_about`
152 - `next_display_order`: `clap::Command::next_display_order`
153 - `next_help_heading`: `clap::Command::next_help_heading`
154 - When `flatten`ing `Args`, this is scoped to just the args in this struct and any struct `flatten`ed into it
155 - `rename_all = <expr>`: Override default field / variant name case conversion for `Command::name` / `Arg::name`
156 - When not present: `kebab-case`
157 - Available values: `camelCase`, `kebab-case`, `PascalCase`, `SCREAMING_SNAKE_CASE`, `snake_case`, `lower`, `UPPER`, `verbatim`
158 - `rename_all_env = <expr>`: Override default field name case conversion for env variables for `clap::Arg::env`
159 - When not present: `SCREAMING_SNAKE_CASE`
160 - Available values: `camelCase`, `kebab-case`, `PascalCase`, `SCREAMING_SNAKE_CASE`, `snake_case`, `lower`, `UPPER`, `verbatim`
161
162 And for `Subcommand` variants:
163 - `skip`: Ignore this variant
164 - `flatten`: Delegates to the variant for more subcommands (must implement `Subcommand`)
165 - `subcommand`: Nest subcommands under the current set of subcommands (must implement `Subcommand`)
166 - `external_subcommand`: `clap::Command::allow_external_subcommand(true)`
167 - Variant must be either `Variant(Vec<String>)` or `Variant(Vec<OsString>)`
168
169 ### Arg Attributes
170
171 These correspond to a `clap::Arg`.
172
173 **Raw attributes:** Any [`Arg` method](https://docs.rs/clap/latest/clap/struct.Arg.html) can also be used as an attribute, see [Terminology](#terminology) for syntax.
174 - e.g. `#[clap(max_values(3))]` would translate to `arg.max_values(3)`
175
176 **Magic attributes**:
177 - `name = <expr>`: `clap::Arg::new`
178 - When not present: case-converted field name is used
179 - `value_parser [= <expr>]`: `clap::Arg::value_parser`
180 - When not present: will auto-select an implementation based on the field type
181 - To register a custom type's `ValueParser`, implement `ValueParserFactory`
182 - When present, implies `#[clap(action)]`
183 - `action [= <expr>]`: `clap::Arg::action`
184 - When not present: will auto-select an action based on the field type
185 - When present, implies `#[clap(value_parser)]`
186 - `help = <expr>`: `clap::Arg::help`
187 - When not present: [Doc comment summary](#doc-comments)
188 - `long_help = <expr>`: `clap::Arg::long_help`
189 - When not present: [Doc comment](#doc-comments) if there is a blank line, else nothing
190 - `verbatim_doc_comment`: Minimizes pre-processing when converting doc comments to `help` / `long_help`
191 - `short [= <char>]`: `clap::Arg::short`
192 - When not present: no short set
193 - Without `<char>`: defaults to first character in the case-converted field name
194 - `long [= <str>]`: `clap::Arg::long`
195 - When not present: no long set
196 - Without `<str>`: defaults to the case-converted field name
197 - `env [= <str>]`: `clap::Arg::env` (needs `env` feature enabled)
198 - When not present: no env set
199 - Without `<str>`: defaults to the case-converted field name
200 - `flatten`: Delegates to the field for more arguments (must implement `Args`)
201 - Only `help_heading` can be used with `flatten`. See
202 [clap-rs/clap#3269](https://github.com/clap-rs/clap/issues/3269) for why
203 arg attributes are not generally supported.
204 - **Tip:** Though we do apply a flattened `Args`'s Parent Command Attributes, this
205 makes reuse harder. Generally prefer putting the cmd attributes on the `Parser`
206 or on the flattened field.
207 - `subcommand`: Delegates definition of subcommands to the field (must implement `Subcommand`)
208 - When `Option<T>`, the subcommand becomes optional
209 - `from_global`: Read a `clap::Arg::global` argument (raw attribute), regardless of what subcommand you are in
210 - `parse(<kind> [= <function>])`: `clap::Arg::validator` and `clap::ArgMatches::values_of_t`
211 - **Deprecated:**
212 - Use `value_parser(...)` for `from_str`, `try_from_str`, `from_os_str`, and `try_from_os_str`
213 - Use `action(ArgAction::Count` for `from_occurrences`
214 - Use `action(ArgAction::SetTrue` for `from_flag`
215 - Default: `try_from_str`
216 - Warning: for `Path` / `OsString`, be sure to use `try_from_os_str`
217 - See [Arg Types](#arg-types) for more details
218 - `value_enum`: Parse the value using the `ValueEnum` trait
219 - `skip [= <expr>]`: Ignore this field, filling in with `<expr>`
220 - Without `<expr>`: fills the field with `Default::default()`
221 - `default_value = <str>`: `clap::Arg::default_value` and `clap::Arg::required(false)`
222 - `default_value_t [= <expr>]`: `clap::Arg::default_value` and `clap::Arg::required(false)`
223 - Requires `std::fmt::Display` or `#[clap(value_enum)]`
224 - Without `<expr>`, relies on `Default::default()`
225 - `default_value_os_t [= <expr>]`: `clap::Arg::default_value_os` and `clap::Arg::required(false)`
226 - Requires `std::convert::Into<OsString>` or `#[clap(value_enum)]`
227 - Without `<expr>`, relies on `Default::default()`
228
229 ### Arg Enum Attributes
230
231 - `rename_all = <expr>`: Override default field / variant name case conversion for `PossibleValue::new`
232 - When not present: `kebab-case`
233 - Available values: `camelCase`, `kebab-case`, `PascalCase`, `SCREAMING_SNAKE_CASE`, `snake_case`, `lower`, `UPPER`, `verbatim`
234
235 ### Possible Value Attributes
236
237 These correspond to a `clap::PossibleValue`.
238
239 **Raw attributes:** Any [`PossibleValue` method](https://docs.rs/clap/latest/clap/struct.PossibleValue.html) can also be used as an attribute, see [Terminology](#terminology) for syntax.
240 - e.g. `#[clap(alias("foo"))]` would translate to `pv.alias("foo")`
241
242 **Magic attributes**:
243 - `name = <expr>`: `clap::PossibleValue::new`
244 - When not present: case-converted field name is used
245 - `help = <expr>`: `clap::PossibleValue::help`
246 - When not present: [Doc comment summary](#doc-comments)
247
248 ## Arg Types
249
250 `clap` assumes some intent based on the type used:
251
252 | Type | Effect | Implies |
253 |---------------------|--------------------------------------|------------------------------------------------------------------|
254 | `bool` | flag | `#[clap(parse(from_flag))]` |
255 | `Option<T>` | optional argument | `.takes_value(true).required(false)` |
256 | `Option<Option<T>>` | optional value for optional argument | `.takes_value(true).required(false).min_values(0).max_values(1)` |
257 | `T` | required argument | `.takes_value(true).required(!has_default)` |
258 | `Vec<T>` | `0..` occurrences of argument | `.takes_value(true).required(false).multiple_occurrences(true)` |
259 | `Option<Vec<T>>` | `0..` occurrences of argument | `.takes_value(true).required(false).multiple_occurrences(true)` |
260
261 Notes:
262 - For custom type behavior, you can override the implied attributes/settings and/or set additional ones
263 - For example, see [custom-bool](./custom-bool.md)
264 - `Option<Vec<T>>` will be `None` instead of `vec![]` if no arguments are provided.
265 - This gives the user some flexibility in designing their argument, like with `min_values(0)`
266
267 You can then support your custom type with `#[clap(parse(<kind> [= <function>]))]`:
268
269 | `<kind>` | Signature | Default `<function>` |
270 |--------------------------|---------------------------------------|---------------------------------|
271 | `from_str` | `fn(&str) -> T` | `::std::convert::From::from` |
272 | `try_from_str` (default) | `fn(&str) -> Result<T, E>` | `::std::str::FromStr::from_str` |
273 | `from_os_str` | `fn(&OsStr) -> T` | `::std::convert::From::from` |
274 | `try_from_os_str` | `fn(&OsStr) -> Result<T, E>` | (no default function) |
275 | `from_occurrences` | `fn(u64) -> T` | `value as T` |
276 | `from_flag` | `fn(bool) -> T` | `::std::convert::From::from` |
277
278 Notes:
279 - `from_os_str`:
280 - Implies `arg.takes_value(true).allow_invalid_utf8(true)`
281 - `try_from_os_str`:
282 - Implies `arg.takes_value(true).allow_invalid_utf8(true)`
283 - `from_occurrences`:
284 - Implies `arg.takes_value(false).multiple_occurrences(true)`
285 - Reads from `clap::ArgMatches::occurrences_of` rather than a `get_one` function
286 - Note: operations on values, like `default_value`, are unlikely to do what you want
287 - `from_flag`
288 - Implies `arg.takes_value(false)`
289 - Reads from `clap::ArgMatches::is_present` rather than a `get_one` function
290 - Note: operations on values, like `default_value`, are unlikely to do what you want
291
292 **Warning:**
293 - To support non-UTF8 paths, you should use `#[clap(value_parser)]` otherwise
294 `clap` will parse it as a `String` which will fail on some paths.
295
296 ## Doc Comments
297
298 In clap, help messages for the whole binary can be specified
299 via [`Command::about`] and [`Command::long_about`] while help messages
300 for individual arguments can be specified via [`Arg::help`] and [`Arg::long_help`]".
301
302 `long_*` variants are used when user calls the program with
303 `--help` and "short" variants are used with `-h` flag.
304
305 ```rust
306 # use clap::Parser;
307
308 #[derive(Parser)]
309 #[clap(about = "I am a program and I work, just pass `-h`", long_about = None)]
310 struct Foo {
311 #[clap(short, help = "Pass `-h` and you'll see me!")]
312 bar: String,
313 }
314 ```
315
316 For convenience, doc comments can be used instead of raw methods
317 (this example works exactly like the one above):
318
319 ```rust
320 # use clap::Parser;
321
322 #[derive(Parser)]
323 /// I am a program and I work, just pass `-h`
324 struct Foo {
325 /// Pass `-h` and you'll see me!
326 bar: String,
327 }
328 ```
329
330 **NOTE:** Attributes have priority over doc comments!
331
332 **Top level doc comments always generate `Command::about/long_about` calls!**
333 If you really want to use the `Command::about/long_about` methods (you likely don't),
334 use the `about` / `long_about` attributes to override the calls generated from
335 the doc comment. To clear `long_about`, you can use
336 `#[clap(long_about = None)]`.
337
338 **TIP:** Set `#![deny(missing_docs)]` to catch missing `--help` documentation at compile time.
339
340 ### Pre-processing
341
342 ```rust
343 # use clap::Parser;
344 #[derive(Parser)]
345 /// Hi there, I'm Robo!
346 ///
347 /// I like beeping, stumbling, eating your electricity,
348 /// and making records of you singing in a shower.
349 /// Pay up, or I'll upload it to youtube!
350 struct Robo {
351 /// Call my brother SkyNet.
352 ///
353 /// I am artificial superintelligence. I won't rest
354 /// until I'll have destroyed humanity. Enjoy your
355 /// pathetic existence, you mere mortals.
356 #[clap(long, action)]
357 kill_all_humans: bool,
358 }
359 ```
360
361 A doc comment consists of three parts:
362 - Short summary
363 - A blank line (whitespace only)
364 - Detailed description, all the rest
365
366 The summary corresponds with `Command::about` / `Arg::help`. When a blank line is
367 present, the whole doc comment will be passed to `Command::long_about` /
368 `Arg::long_help`. Or in other words, a doc may result in just a `Command::about` /
369 `Arg::help` or `Command::about` / `Arg::help` and `Command::long_about` /
370 `Arg::long_help`
371
372 In addition, when `verbatim_doc_comment` is not present, `clap` applies some preprocessing, including:
373
374 - Strip leading and trailing whitespace from every line, if present.
375
376 - Strip leading and trailing blank lines, if present.
377
378 - Interpret each group of non-empty lines as a word-wrapped paragraph.
379
380 We replace newlines within paragraphs with spaces to allow the output
381 to be re-wrapped to the terminal width.
382
383 - Strip any excess blank lines so that there is exactly one per paragraph break.
384
385 - If the first paragraph ends in exactly one period,
386 remove the trailing period (i.e. strip trailing periods but not trailing ellipses).
387
388 Sometimes you don't want this preprocessing to apply, for example the comment contains
389 some ASCII art or markdown tables, you would need to preserve LFs along with
390 blank lines and the leading/trailing whitespace. When you pass use the
391 `verbatim_doc_comment` magic attribute, you preserve
392 them.
393
394 **Note:** Keep in mind that `verbatim_doc_comment` will *still*
395 - Remove one leading space from each line, even if this attribute is present,
396 to allow for a space between `///` and the content.
397 - Remove leading and trailing blank lines
398
399 ## Tips
400
401 - To get access to a `Command` call `CommandFactory::command` (implemented when deriving `Parser`)
402 - Proactively check for bad `Command` configurations by calling `Command::debug_assert` in a test ([example](../tutorial_derive/05_01_assert.rs))
403
404 ## Mixing Builder and Derive APIs
405
406 The builder and derive APIs do not live in isolation. They can work together, which is especially helpful if some arguments can be specified at compile-time while others must be specified at runtime.
407
408 ### Using derived arguments in a builder application
409
410 *[Jump to source](augment_args.rs)*
411
412 When using the derive API, you can `#[clap(flatten)]` a struct deriving `Args` into a struct deriving `Args` or `Parser`. This example shows how you can augment a `Command` instance created using the builder API with `Args` created using the derive API.
413
414 It uses the `Args::augment_args` method to add the arguments to the `Command` instance.
415
416 Crates such as [clap-verbosity-flag](https://github.com/rust-cli/clap-verbosity-flag) provide structs that implement `Args` or `Parser`. Without the technique shown in this example, it would not be possible to use such crates with the builder API. `augment_args` to the rescue!
417
418 ### Using derived subcommands in a builder application
419
420 *[Jump to source](augment_subcommands.rs)*
421
422 When using the derive API, you can use `#[clap(subcommand)]` inside the struct to add subcommands. The type of the field is usually an enum that derived `Parser`. However, you can also add the subcommands in that enum to a `Command` instance created with the builder API.
423
424 It uses the `Subcommand::augment_subcommands` method to add the subcommands to the `Command` instance.
425
426 ### Adding hand-implemented subcommands to a derived application
427
428 *[Jump to source](hand_subcommand.rs)*
429
430 When using the derive API, you can use `#[clap(subcommand)]` inside the struct to add subcommands. The type of the field is usually an enum that derived `Parser`. However, you can also implement the `Subcommand` trait manually on this enum (or any other type) and it can still be used inside the struct created with the derive API. The implementation of the `Subcommand` trait will use the builder API to add the subcommands to the `Command` instance created behind the scenes for you by the derive API.
431
432 Notice how in the previous example we used `augment_subcommands` on an enum that derived `Parser`, whereas now we implement `augment_subcommands` ourselves, but the derive API calls it automatically since we used the `#[clap(subcommand)]` attribute.
433
434 ### Flattening hand-implemented args into a derived application
435
436 *[Jump to source](flatten_hand_args.rs)*
437
438 When using the derive API, you can use `#[clap(flatten)]` inside the struct to add arguments as if they were added directly to the containing struct. The type of the field is usually an struct that derived `Args`. However, you can also implement the `Args` trait manually on this struct (or any other type) and it can still be used inside the struct created with the derive API. The implementation of the `Args` trait will use the builder API to add the arguments to the `Command` instance created behind the scenes for you by the derive API.
439
440 Notice how in the example 1 we used `augment_args` on the struct that derived `Parser`, whereas now we implement `augment_args` ourselves, but the derive API calls it automatically since we used the `#[clap(flatten)]` attribute.