|
| 1 | +// Contributing |
| 2 | +// |
| 3 | +// New example code: |
| 4 | +// - Please update the corresponding section in the derive tutorial |
| 5 | +// - Building: They must be added to `Cargo.toml` with the appropriate `required-features`. |
| 6 | +// - Testing: Ensure there is a markdown file with [trycmd](https://docs.rs/trycmd) syntax |
| 7 | +// |
| 8 | +// See also the general CONTRIBUTING |
| 9 | + |
| 10 | +//! ## Tutorial for the Derive API |
| 11 | +//! |
| 12 | +//! *See the side bar for the Table of Contents* |
| 13 | +//! |
| 14 | +//! ## Quick Start |
| 15 | +//! |
| 16 | +//! You can create an application declaratively with a `struct` and some |
| 17 | +//! attributes. |
| 18 | +//! |
| 19 | +//! First, ensure `clap` is available with the [`derive` feature flag][crate::_features]: |
| 20 | +//! ```console |
| 21 | +//! $ cargo add clap --features derive |
| 22 | +//! ``` |
| 23 | +//! |
| 24 | +//! Here is a preview of the type of application you can make: |
| 25 | +//! ```rust |
| 26 | +#![doc = include_str!("../../examples/tutorial_derive/01_quick.rs")] |
| 27 | +//! ``` |
| 28 | +//! |
| 29 | +#![doc = include_str!("../../examples/tutorial_derive/01_quick.md")] |
| 30 | +//! |
| 31 | +//! See also |
| 32 | +//! - [FAQ: When should I use the builder vs derive APIs?][crate::_faq#when-should-i-use-the-builder-vs-derive-apis] |
| 33 | +//! - The [cookbook][crate::_cookbook] for more application-focused examples |
| 34 | +//! |
| 35 | +//! ## Configuring the Parser |
| 36 | +//! |
| 37 | +//! You use derive [`Parser`][crate::Parser] to start building a parser. |
| 38 | +//! |
| 39 | +//! ```rust |
| 40 | +#![doc = include_str!("../../examples/tutorial_derive/02_apps.rs")] |
| 41 | +//! ``` |
| 42 | +//! |
| 43 | +#![doc = include_str!("../../examples/tutorial_derive/02_apps.md")] |
| 44 | +//! |
| 45 | +//! You can use [`#[command(version, about)]` attribute defaults][super#command-attributes] on the struct to fill these fields in from your `Cargo.toml` file. |
| 46 | +//! |
| 47 | +//! ```rust |
| 48 | +#![doc = include_str!("../../examples/tutorial_derive/02_crate.rs")] |
| 49 | +//! ``` |
| 50 | +#![doc = include_str!("../../examples/tutorial_derive/02_crate.md")] |
| 51 | +//! |
| 52 | +//! You can use `#[command]` attributes on the struct to change the application level behavior of clap. Any [`Command`][crate::Command] builder function can be used as an attribute, like [`Command::next_line_help`]. |
| 53 | +//! |
| 54 | +//! ```rust |
| 55 | +#![doc = include_str!("../../examples/tutorial_derive/02_app_settings.rs")] |
| 56 | +//! ``` |
| 57 | +#![doc = include_str!("../../examples/tutorial_derive/02_app_settings.md")] |
| 58 | +//! |
| 59 | +//! ## Adding Arguments |
| 60 | +//! |
| 61 | +//! 1. [Positionals](#positionals) |
| 62 | +//! 2. [Options](#options) |
| 63 | +//! 3. [Flags](#flags) |
| 64 | +//! 4. [Subcommands](#subcommands) |
| 65 | +//! 5. [Defaults](#defaults) |
| 66 | +//! |
| 67 | +//! Arguments are inferred from the fields of your struct. |
| 68 | +//! |
| 69 | +//! ### Positionals |
| 70 | +//! |
| 71 | +//! By default, struct fields define positional arguments: |
| 72 | +//! |
| 73 | +//! ```rust |
| 74 | +#![doc = include_str!("../../examples/tutorial_derive/03_03_positional.rs")] |
| 75 | +//! ``` |
| 76 | +#![doc = include_str!("../../examples/tutorial_derive/03_03_positional.md")] |
| 77 | +//! |
| 78 | +//! Note that the [default `ArgAction` is `Set`][super#arg-types]. To |
| 79 | +//! accept multiple values, override the [action][Arg::action] with [`Append`][crate::ArgAction::Append] via `Vec`: |
| 80 | +//! ```rust |
| 81 | +#![doc = include_str!("../../examples/tutorial_derive/03_03_positional_mult.rs")] |
| 82 | +//! ``` |
| 83 | +#![doc = include_str!("../../examples/tutorial_derive/03_03_positional_mult.md")] |
| 84 | +//! |
| 85 | +//! ### Options |
| 86 | +//! |
| 87 | +//! You can name your arguments with a flag: |
| 88 | +//! - Order doesn't matter |
| 89 | +//! - They can be optional |
| 90 | +//! - Intent is clearer |
| 91 | +//! |
| 92 | +//! To specify the flags for an argument, you can use [`#[arg(short = 'n')]`][Arg::short] and/or |
| 93 | +//! [`#[arg(long = "name")]`][Arg::long] attributes on a field. When no value is given (e.g. |
| 94 | +//! `#[arg(short)]`), the flag is inferred from the field's name. |
| 95 | +//! |
| 96 | +//! ```rust |
| 97 | +#![doc = include_str!("../../examples/tutorial_derive/03_02_option.rs")] |
| 98 | +//! ``` |
| 99 | +#![doc = include_str!("../../examples/tutorial_derive/03_02_option.md")] |
| 100 | +//! |
| 101 | +//! Note that the [default `ArgAction` is `Set`][super#arg-types]. To |
| 102 | +//! accept multiple occurrences, override the [action][Arg::action] with [`Append`][crate::ArgAction::Append] via `Vec`: |
| 103 | +//! ```rust |
| 104 | +#![doc = include_str!("../../examples/tutorial_derive/03_02_option_mult.rs")] |
| 105 | +//! ``` |
| 106 | +#![doc = include_str!("../../examples/tutorial_derive/03_02_option_mult.md")] |
| 107 | +//! |
| 108 | +//! ### Flags |
| 109 | +//! |
| 110 | +//! Flags can also be switches that can be on/off: |
| 111 | +//! |
| 112 | +//! ```rust |
| 113 | +#![doc = include_str!("../../examples/tutorial_derive/03_01_flag_bool.rs")] |
| 114 | +//! ``` |
| 115 | +#![doc = include_str!("../../examples/tutorial_derive/03_01_flag_bool.md")] |
| 116 | +//! |
| 117 | +//! Note that the [default `ArgAction` for a `bool` field is |
| 118 | +//! `SetTrue`][super#arg-types]. To accept multiple flags, override the [action][Arg::action] with |
| 119 | +//! [`Count`][crate::ArgAction::Count]: |
| 120 | +//! |
| 121 | +//! ```rust |
| 122 | +#![doc = include_str!("../../examples/tutorial_derive/03_01_flag_count.rs")] |
| 123 | +//! ``` |
| 124 | +#![doc = include_str!("../../examples/tutorial_derive/03_01_flag_count.md")] |
| 125 | +//! |
| 126 | +//! This also shows that any[`Arg`][crate::Args] method may be used as an attribute. |
| 127 | +//! |
| 128 | +//! ### Subcommands |
| 129 | +//! |
| 130 | +//! Subcommands are derived with `#[derive(Subcommand)]` and be added via |
| 131 | +//! [`#[command(subcommand)]` attribute][super#command-attributes] on the field using that type. |
| 132 | +//! Each instance of a [Subcommand][crate::Subcommand] can have its own version, author(s), Args, |
| 133 | +//! and even its own subcommands. |
| 134 | +//! |
| 135 | +//! ```rust |
| 136 | +#![doc = include_str!("../../examples/tutorial_derive/03_04_subcommands.rs")] |
| 137 | +//! ``` |
| 138 | +//! We used a struct-variant to define the `add` subcommand. |
| 139 | +//! Alternatively, you can use a struct for your subcommand's arguments: |
| 140 | +//! ```rust |
| 141 | +#![doc = include_str!("../../examples/tutorial_derive/03_04_subcommands_alt.rs")] |
| 142 | +//! ``` |
| 143 | +//! |
| 144 | +#![doc = include_str!("../../examples/tutorial_derive/03_04_subcommands.md")] |
| 145 | +//! |
| 146 | +//! ### Defaults |
| 147 | +//! |
| 148 | +//! We've previously showed that arguments can be [`required`][crate::Arg::required] or optional. |
| 149 | +//! When optional, you work with a `Option` and can `unwrap_or`. Alternatively, you can |
| 150 | +//! set [`#[arg(default_value_t)]`][super#arg-attributes]. |
| 151 | +//! |
| 152 | +//! ```rust |
| 153 | +#![doc = include_str!("../../examples/tutorial_derive/03_05_default_values.rs")] |
| 154 | +//! ``` |
| 155 | +#![doc = include_str!("../../examples/tutorial_derive/03_05_default_values.md")] |
| 156 | +//! |
| 157 | +//! ## Validation |
| 158 | +//! |
| 159 | +//! 1. [Enumerated values](#enumerated-values) |
| 160 | +//! 2. [Validated values](#validated-values) |
| 161 | +//! 3. [Argument Relations](#argument-relations) |
| 162 | +//! 4. [Custom Validation](#custom-validation) |
| 163 | +//! |
| 164 | +//! An appropriate default parser/validator will be selected for the field's type. See |
| 165 | +//! [`value_parser!`][crate::value_parser!] for more details. |
| 166 | +//! |
| 167 | +//! ### Enumerated values |
| 168 | +//! |
| 169 | +//! For example, if you have arguments of specific values you want to test for, you can derive |
| 170 | +//! [`ValueEnum`][super#valueenum-attributes] |
| 171 | +//! (any [`PossibleValue`] builder function can be used as a `#[value]` attribute on enum variants). |
| 172 | +//! |
| 173 | +//! This allows you specify the valid values for that argument. If the user does not use one of |
| 174 | +//! those specific values, they will receive a graceful exit with error message informing them |
| 175 | +//! of the mistake, and what the possible valid values are |
| 176 | +//! |
| 177 | +//! ```rust |
| 178 | +#![doc = include_str!("../../examples/tutorial_derive/04_01_enum.rs")] |
| 179 | +//! ``` |
| 180 | +#![doc = include_str!("../../examples/tutorial_derive/04_01_enum.md")] |
| 181 | +//! |
| 182 | +//! ### Validated values |
| 183 | +//! |
| 184 | +//! More generally, you can validate and parse into any data type with [`Arg::value_parser`]. |
| 185 | +//! |
| 186 | +//! ```rust |
| 187 | +#![doc = include_str!("../../examples/tutorial_derive/04_02_parse.rs")] |
| 188 | +//! ``` |
| 189 | +#![doc = include_str!("../../examples/tutorial_derive/04_02_parse.md")] |
| 190 | +//! |
| 191 | +//! A [custom parser][TypedValueParser] can be used to improve the error messages or provide additional validation: |
| 192 | +//! |
| 193 | +//! ```rust |
| 194 | +#![doc = include_str!("../../examples/tutorial_derive/04_02_validate.rs")] |
| 195 | +//! ``` |
| 196 | +#![doc = include_str!("../../examples/tutorial_derive/04_02_validate.md")] |
| 197 | +//! |
| 198 | +//! See [`Arg::value_parser`][crate::Arg::value_parser] for more details. |
| 199 | +//! |
| 200 | +//! ### Argument Relations |
| 201 | +//! |
| 202 | +//! You can declare dependencies or conflicts between [`Arg`][crate::Arg]s or even |
| 203 | +//! [`ArgGroup`][crate::ArgGroup]s. |
| 204 | +//! |
| 205 | +//! [`ArgGroup`][crate::ArgGroup]s make it easier to declare relations instead of having to list |
| 206 | +//! each individually, or when you want a rule to apply "any but not all" arguments. |
| 207 | +//! |
| 208 | +//! Perhaps the most common use of [`ArgGroup`][crate::ArgGroup]s is to require one and *only* one |
| 209 | +//! argument to be present out of a given set. Imagine that you had multiple arguments, and you |
| 210 | +//! want one of them to be required, but making all of them required isn't feasible because perhaps |
| 211 | +//! they conflict with each other. |
| 212 | +//! |
| 213 | +//! [`ArgGroup`][crate::ArgGroup]s are automatically created for a `struct` with its |
| 214 | +//! [`ArgGroup::id`][crate::ArgGroup::id] being the struct's name. |
| 215 | +//! |
| 216 | +//! ```rust |
| 217 | +#![doc = include_str!("../../examples/tutorial_derive/04_03_relations.rs")] |
| 218 | +//! ``` |
| 219 | +#![doc = include_str!("../../examples/tutorial_derive/04_03_relations.md")] |
| 220 | +//! |
| 221 | +//! ### Custom Validation |
| 222 | +//! |
| 223 | +//! As a last resort, you can create custom errors with the basics of clap's formatting. |
| 224 | +//! |
| 225 | +//! ```rust |
| 226 | +#![doc = include_str!("../../examples/tutorial_derive/04_04_custom.rs")] |
| 227 | +//! ``` |
| 228 | +#![doc = include_str!("../../examples/tutorial_derive/04_04_custom.md")] |
| 229 | +//! |
| 230 | +//! ## Testing |
| 231 | +//! |
| 232 | +//! clap reports most development errors as `debug_assert!`s. Rather than checking every |
| 233 | +//! subcommand, you should have a test that calls |
| 234 | +//! [`Command::debug_assert`][crate::Command::debug_assert]: |
| 235 | +//! ```rust,no_run |
| 236 | +#![doc = include_str!("../../examples/tutorial_derive/05_01_assert.rs")] |
| 237 | +//! ``` |
| 238 | +//! |
| 239 | +//! ## Next Steps |
| 240 | +//! |
| 241 | +//! - [Cookbook][crate::_cookbook] for application-focused examples |
| 242 | +//! - Explore more features in the [Derive reference][super] |
| 243 | +//! - See also [`Command`], [`Arg`], [`ArgGroup`], and [`PossibleValue`] builder functions which |
| 244 | +//! can be used as attributes |
| 245 | +//! |
| 246 | +//! For support, see [Discussions](https://github.com/clap-rs/clap/discussions) |
| 247 | +#![allow(unused_imports)] |
| 248 | +use crate::builder::*; |
0 commit comments