Skip to content

Commit fea7c54

Browse files
authored
Merge pull request #5888 from epage/tut
docs(tutorial): Experiment with a flat layout
2 parents e01e2b9 + c297ddd commit fea7c54

18 files changed

+492
-596
lines changed

src/_derive/_tutorial.rs

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
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::*;

src/_derive/_tutorial/chapter_0.rs

Lines changed: 0 additions & 25 deletions
This file was deleted.

src/_derive/_tutorial/chapter_1.rs

Lines changed: 0 additions & 29 deletions
This file was deleted.

0 commit comments

Comments
 (0)