Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(tutorial): Experiment with a flat layout #5888

Merged
merged 3 commits into from
Jan 20, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
248 changes: 248 additions & 0 deletions src/_derive/_tutorial.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
// Contributing
//
// New example code:
// - Please update the corresponding section in the derive tutorial
// - Building: They must be added to `Cargo.toml` with the appropriate `required-features`.
// - Testing: Ensure there is a markdown file with [trycmd](https://docs.rs/trycmd) syntax
//
// See also the general CONTRIBUTING

//! ## Tutorial for the Derive API
//!
//! *See the side bar for the Table of Contents*
//!
//! ## Quick Start
//!
//! You can create an application declaratively with a `struct` and some
//! attributes.
//!
//! First, ensure `clap` is available with the [`derive` feature flag][crate::_features]:
//! ```console
//! $ cargo add clap --features derive
//! ```
//!
//! Here is a preview of the type of application you can make:
//! ```rust
#![doc = include_str!("../../examples/tutorial_derive/01_quick.rs")]
//! ```
//!
#![doc = include_str!("../../examples/tutorial_derive/01_quick.md")]
//!
//! See also
//! - [FAQ: When should I use the builder vs derive APIs?][crate::_faq#when-should-i-use-the-builder-vs-derive-apis]
//! - The [cookbook][crate::_cookbook] for more application-focused examples
//!
//! ## Configuring the Parser
//!
//! You use derive [`Parser`][crate::Parser] to start building a parser.
//!
//! ```rust
#![doc = include_str!("../../examples/tutorial_derive/02_apps.rs")]
//! ```
//!
#![doc = include_str!("../../examples/tutorial_derive/02_apps.md")]
//!
//! You can use [`#[command(version, about)]` attribute defaults][super#command-attributes] on the struct to fill these fields in from your `Cargo.toml` file.
//!
//! ```rust
#![doc = include_str!("../../examples/tutorial_derive/02_crate.rs")]
//! ```
#![doc = include_str!("../../examples/tutorial_derive/02_crate.md")]
//!
//! 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`].
//!
//! ```rust
#![doc = include_str!("../../examples/tutorial_derive/02_app_settings.rs")]
//! ```
#![doc = include_str!("../../examples/tutorial_derive/02_app_settings.md")]
//!
//! ## Adding Arguments
//!
//! 1. [Positionals](#positionals)
//! 2. [Options](#options)
//! 3. [Flags](#flags)
//! 4. [Subcommands](#subcommands)
//! 5. [Defaults](#defaults)
//!
//! Arguments are inferred from the fields of your struct.
//!
//! ### Positionals
//!
//! By default, struct fields define positional arguments:
//!
//! ```rust
#![doc = include_str!("../../examples/tutorial_derive/03_03_positional.rs")]
//! ```
#![doc = include_str!("../../examples/tutorial_derive/03_03_positional.md")]
//!
//! Note that the [default `ArgAction` is `Set`][super#arg-types]. To
//! accept multiple values, override the [action][Arg::action] with [`Append`][crate::ArgAction::Append] via `Vec`:
//! ```rust
#![doc = include_str!("../../examples/tutorial_derive/03_03_positional_mult.rs")]
//! ```
#![doc = include_str!("../../examples/tutorial_derive/03_03_positional_mult.md")]
//!
//! ### Options
//!
//! You can name your arguments with a flag:
//! - Order doesn't matter
//! - They can be optional
//! - Intent is clearer
//!
//! To specify the flags for an argument, you can use [`#[arg(short = 'n')]`][Arg::short] and/or
//! [`#[arg(long = "name")]`][Arg::long] attributes on a field. When no value is given (e.g.
//! `#[arg(short)]`), the flag is inferred from the field's name.
//!
//! ```rust
#![doc = include_str!("../../examples/tutorial_derive/03_02_option.rs")]
//! ```
#![doc = include_str!("../../examples/tutorial_derive/03_02_option.md")]
//!
//! Note that the [default `ArgAction` is `Set`][super#arg-types]. To
//! accept multiple occurrences, override the [action][Arg::action] with [`Append`][crate::ArgAction::Append] via `Vec`:
//! ```rust
#![doc = include_str!("../../examples/tutorial_derive/03_02_option_mult.rs")]
//! ```
#![doc = include_str!("../../examples/tutorial_derive/03_02_option_mult.md")]
//!
//! ### Flags
//!
//! Flags can also be switches that can be on/off:
//!
//! ```rust
#![doc = include_str!("../../examples/tutorial_derive/03_01_flag_bool.rs")]
//! ```
#![doc = include_str!("../../examples/tutorial_derive/03_01_flag_bool.md")]
//!
//! Note that the [default `ArgAction` for a `bool` field is
//! `SetTrue`][super#arg-types]. To accept multiple flags, override the [action][Arg::action] with
//! [`Count`][crate::ArgAction::Count]:
//!
//! ```rust
#![doc = include_str!("../../examples/tutorial_derive/03_01_flag_count.rs")]
//! ```
#![doc = include_str!("../../examples/tutorial_derive/03_01_flag_count.md")]
//!
//! This also shows that any[`Arg`][crate::Args] method may be used as an attribute.
//!
//! ### Subcommands
//!
//! Subcommands are derived with `#[derive(Subcommand)]` and be added via
//! [`#[command(subcommand)]` attribute][super#command-attributes] on the field using that type.
//! Each instance of a [Subcommand][crate::Subcommand] can have its own version, author(s), Args,
//! and even its own subcommands.
//!
//! ```rust
#![doc = include_str!("../../examples/tutorial_derive/03_04_subcommands.rs")]
//! ```
//! We used a struct-variant to define the `add` subcommand.
//! Alternatively, you can use a struct for your subcommand's arguments:
//! ```rust
#![doc = include_str!("../../examples/tutorial_derive/03_04_subcommands_alt.rs")]
//! ```
//!
#![doc = include_str!("../../examples/tutorial_derive/03_04_subcommands.md")]
//!
//! ### Defaults
//!
//! We've previously showed that arguments can be [`required`][crate::Arg::required] or optional.
//! When optional, you work with a `Option` and can `unwrap_or`. Alternatively, you can
//! set [`#[arg(default_value_t)]`][super#arg-attributes].
//!
//! ```rust
#![doc = include_str!("../../examples/tutorial_derive/03_05_default_values.rs")]
//! ```
#![doc = include_str!("../../examples/tutorial_derive/03_05_default_values.md")]
//!
//! ## Validation
//!
//! 1. [Enumerated values](#enumerated-values)
//! 2. [Validated values](#validated-values)
//! 3. [Argument Relations](#argument-relations)
//! 4. [Custom Validation](#custom-validation)
//!
//! An appropriate default parser/validator will be selected for the field's type. See
//! [`value_parser!`][crate::value_parser!] for more details.
//!
//! ### Enumerated values
//!
//! For example, if you have arguments of specific values you want to test for, you can derive
//! [`ValueEnum`][super#valueenum-attributes]
//! (any [`PossibleValue`] builder function can be used as a `#[value]` attribute on enum variants).
//!
//! This allows you specify the valid values for that argument. If the user does not use one of
//! those specific values, they will receive a graceful exit with error message informing them
//! of the mistake, and what the possible valid values are
//!
//! ```rust
#![doc = include_str!("../../examples/tutorial_derive/04_01_enum.rs")]
//! ```
#![doc = include_str!("../../examples/tutorial_derive/04_01_enum.md")]
//!
//! ### Validated values
//!
//! More generally, you can validate and parse into any data type with [`Arg::value_parser`].
//!
//! ```rust
#![doc = include_str!("../../examples/tutorial_derive/04_02_parse.rs")]
//! ```
#![doc = include_str!("../../examples/tutorial_derive/04_02_parse.md")]
//!
//! A [custom parser][TypedValueParser] can be used to improve the error messages or provide additional validation:
//!
//! ```rust
#![doc = include_str!("../../examples/tutorial_derive/04_02_validate.rs")]
//! ```
#![doc = include_str!("../../examples/tutorial_derive/04_02_validate.md")]
//!
//! See [`Arg::value_parser`][crate::Arg::value_parser] for more details.
//!
//! ### Argument Relations
//!
//! You can declare dependencies or conflicts between [`Arg`][crate::Arg]s or even
//! [`ArgGroup`][crate::ArgGroup]s.
//!
//! [`ArgGroup`][crate::ArgGroup]s make it easier to declare relations instead of having to list
//! each individually, or when you want a rule to apply "any but not all" arguments.
//!
//! Perhaps the most common use of [`ArgGroup`][crate::ArgGroup]s is to require one and *only* one
//! argument to be present out of a given set. Imagine that you had multiple arguments, and you
//! want one of them to be required, but making all of them required isn't feasible because perhaps
//! they conflict with each other.
//!
//! [`ArgGroup`][crate::ArgGroup]s are automatically created for a `struct` with its
//! [`ArgGroup::id`][crate::ArgGroup::id] being the struct's name.
//!
//! ```rust
#![doc = include_str!("../../examples/tutorial_derive/04_03_relations.rs")]
//! ```
#![doc = include_str!("../../examples/tutorial_derive/04_03_relations.md")]
//!
//! ### Custom Validation
//!
//! As a last resort, you can create custom errors with the basics of clap's formatting.
//!
//! ```rust
#![doc = include_str!("../../examples/tutorial_derive/04_04_custom.rs")]
//! ```
#![doc = include_str!("../../examples/tutorial_derive/04_04_custom.md")]
//!
//! ## Testing
//!
//! clap reports most development errors as `debug_assert!`s. Rather than checking every
//! subcommand, you should have a test that calls
//! [`Command::debug_assert`][crate::Command::debug_assert]:
//! ```rust,no_run
#![doc = include_str!("../../examples/tutorial_derive/05_01_assert.rs")]
//! ```
//!
//! ## Next Steps
//!
//! - [Cookbook][crate::_cookbook] for application-focused examples
//! - Explore more features in the [Derive reference][super]
//! - See also [`Command`], [`Arg`], [`ArgGroup`], and [`PossibleValue`] builder functions which
//! can be used as attributes
//!
//! For support, see [Discussions](https://github.com/clap-rs/clap/discussions)
#![allow(unused_imports)]
use crate::builder::*;
25 changes: 0 additions & 25 deletions src/_derive/_tutorial/chapter_0.rs

This file was deleted.

29 changes: 0 additions & 29 deletions src/_derive/_tutorial/chapter_1.rs

This file was deleted.

103 changes: 0 additions & 103 deletions src/_derive/_tutorial/chapter_2.rs

This file was deleted.

78 changes: 0 additions & 78 deletions src/_derive/_tutorial/chapter_3.rs

This file was deleted.

15 changes: 0 additions & 15 deletions src/_derive/_tutorial/chapter_4.rs

This file was deleted.

14 changes: 0 additions & 14 deletions src/_derive/_tutorial/chapter_5.rs

This file was deleted.

36 changes: 0 additions & 36 deletions src/_derive/_tutorial/mod.rs

This file was deleted.

10 changes: 5 additions & 5 deletions src/_derive/mod.rs
Original file line number Diff line number Diff line change
@@ -194,8 +194,8 @@
//! [`Subcommand`][crate::Subcommand])
//! - When `Option<T>`, the subcommand becomes optional
//!
//! See [Configuring the Parser][_tutorial::chapter_1] and
//! [Subcommands][_tutorial::chapter_2#subcommands] from the tutorial.
//! See [Configuring the Parser][_tutorial#configuring-the-parser] and
//! [Subcommands][_tutorial#subcommands] from the tutorial.
//!
//! ### ArgGroup Attributes
//!
@@ -215,7 +215,7 @@
//! - For `struct`s, [`multiple = true`][crate::ArgGroup::multiple] is implied
//! - `enum` support is tracked at [#2621](https://github.com/clap-rs/clap/issues/2621)
//!
//! See [Argument Relations][_tutorial::chapter_3#argument-relations] from the tutorial.
//! See [Argument Relations][_tutorial#argument-relations] from the tutorial.
//!
//! ### Arg Attributes
//!
@@ -269,7 +269,7 @@
//! - Requires field arg to be of type `Vec<T>` and `T` to implement `std::convert::Into<OsString>` or `#[arg(value_enum)]`
//! - `<expr>` must implement `IntoIterator<T>`
//!
//! See [Adding Arguments][_tutorial::chapter_2] and [Validation][_tutorial::chapter_3] from the
//! See [Adding Arguments][_tutorial#adding-arguments] and [Validation][_tutorial#validation] from the
//! tutorial.
//!
//! ### ValueEnum Attributes
@@ -278,7 +278,7 @@
//! - When not present: `"kebab-case"`
//! - Available values: `"camelCase"`, `"kebab-case"`, `"PascalCase"`, `"SCREAMING_SNAKE_CASE"`, `"snake_case"`, `"lower"`, `"UPPER"`, `"verbatim"`
//!
//! See [Enumerated values][_tutorial::chapter_3#enumerated-values] from the tutorial.
//! See [Enumerated values][_tutorial#enumerated-values] from the tutorial.
//!
//! ### Possible Value Attributes
//!
237 changes: 237 additions & 0 deletions src/_tutorial.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
// Contributing
//
// New example code:
// - Please update the corresponding section in the derive tutorial
// - Building: They must be added to `Cargo.toml` with the appropriate `required-features`.
// - Testing: Ensure there is a markdown file with [trycmd](https://docs.rs/trycmd) syntax
//
// See also the general CONTRIBUTING

//! ## Tutorial for the Builder API
//!
//! *See the side bar for the Table of Contents*
//!
//! ## Quick Start
//!
//! You can create an application with several arguments using usage strings.
//!
//! First, ensure `clap` is available:
//! ```console
//! $ cargo add clap
//! ```
//!
//! Here is a preview of the type of application you can make:
//! ```rust
#![doc = include_str!("../examples/tutorial_builder/01_quick.rs")]
//! ```
//!
#![doc = include_str!("../examples/tutorial_builder/01_quick.md")]
//!
//! See also
//! - [FAQ: When should I use the builder vs derive APIs?][crate::_faq#when-should-i-use-the-builder-vs-derive-apis]
//! - The [cookbook][crate::_cookbook] for more application-focused examples
//!
//! ## Configuring the Parser
//!
//! You use [`Command`][crate::Command] to start building a parser.
//!
//! ```rust
#![doc = include_str!("../examples/tutorial_builder/02_apps.rs")]
//! ```
//!
#![doc = include_str!("../examples/tutorial_builder/02_apps.md")]
//!
//! You can use [`command!()`][crate::command!] to fill these fields in from your `Cargo.toml`
//! file. **This requires the [`cargo` feature flag][crate::_features].**
//!
//! ```rust
#![doc = include_str!("../examples/tutorial_builder/02_crate.rs")]
//! ```
#![doc = include_str!("../examples/tutorial_builder/02_crate.md")]
//!
//! You can use [`Command`][crate::Command] methods to change the application level behavior of
//! clap, like [`Command::next_line_help`].
//!
//! ```rust
#![doc = include_str!("../examples/tutorial_builder/02_app_settings.rs")]
//! ```
#![doc = include_str!("../examples/tutorial_builder/02_app_settings.md")]
//!
//! ## Adding Arguments
//!
//! 1. [Positionals](#positionals)
//! 2. [Options](#options)
//! 3. [Flags](#flags)
//! 4. [Subcommands](#subcommands)
//! 5. [Defaults](#defaults)
//!
//!
//! ### Positionals
//!
//! By default, an [`Arg`] defines a positional argument:
//!
//! ```rust
#![doc = include_str!("../examples/tutorial_builder/03_03_positional.rs")]
//! ```
#![doc = include_str!("../examples/tutorial_builder/03_03_positional.md")]
//!
//! Note that the default [`ArgAction`][crate::ArgAction] is [`Set`][crate::ArgAction::Set]. To
//! accept multiple values, override the [action][Arg::action] with [`Append`][crate::ArgAction::Append]:
//! ```rust
#![doc = include_str!("../examples/tutorial_builder/03_03_positional_mult.rs")]
//! ```
#![doc = include_str!("../examples/tutorial_builder/03_03_positional_mult.md")]
//!
//! ### Options
//!
//! You can name your arguments with a flag:
//! - Order doesn't matter
//! - They can be optional
//! - Intent is clearer
//!
//! ```rust
#![doc = include_str!("../examples/tutorial_builder/03_02_option.rs")]
//! ```
#![doc = include_str!("../examples/tutorial_builder/03_02_option.md")]
//!
//! Note that the default [`ArgAction`][crate::ArgAction] is [`Set`][crate::ArgAction::Set]. To
//! accept multiple occurrences, override the [action][Arg::action] with [`Append`][crate::ArgAction::Append]:
//! ```rust
#![doc = include_str!("../examples/tutorial_builder/03_02_option_mult.rs")]
//! ```
#![doc = include_str!("../examples/tutorial_builder/03_02_option_mult.md")]
//!
//! ### Flags
//!
//! Flags can also be switches that can be on/off:
//!
//! ```rust
#![doc = include_str!("../examples/tutorial_builder/03_01_flag_bool.rs")]
//! ```
#![doc = include_str!("../examples/tutorial_builder/03_01_flag_bool.md")]
//!
//! To accept multiple flags, use [`Count`][crate::ArgAction::Count]:
//!
//! ```rust
#![doc = include_str!("../examples/tutorial_builder/03_01_flag_count.rs")]
//! ```
#![doc = include_str!("../examples/tutorial_builder/03_01_flag_count.md")]
//!
//! ### Subcommands
//!
//! Subcommands are defined as [`Command`][crate::Command]s that get added via
//! [`Command::subcommand`][crate::Command::subcommand]. Each instance of a Subcommand can have its
//! own version, author(s), Args, and even its own subcommands.
//!
//! ```rust
#![doc = include_str!("../examples/tutorial_builder/03_04_subcommands.rs")]
//! ```
#![doc = include_str!("../examples/tutorial_builder/03_04_subcommands.md")]
//!
//! ### Defaults
//!
//! We've previously showed that arguments can be [`required`][crate::Arg::required] or optional.
//! When optional, you work with a `Option` and can `unwrap_or`. Alternatively, you can set
//! [`Arg::default_value`][crate::Arg::default_value].
//!
//! ```rust
#![doc = include_str!("../examples/tutorial_builder/03_05_default_values.rs")]
//! ```
#![doc = include_str!("../examples/tutorial_builder/03_05_default_values.md")]
//!
//! ## Validation
//!
//! 1. [Enumerated values](#enumerated-values)
//! 2. [Validated values](#validated-values)
//! 3. [Argument Relations](#argument-relations)
//! 4. [Custom Validation](#custom-validation)
//!
//! An appropriate default parser/validator will be selected for the field's type. See
//! [`value_parser!`][crate::value_parser!] for more details.
//!
//! ### Enumerated values
//!
//! If you have arguments of specific values you want to test for, you can use the
//! [`PossibleValuesParser`][crate::builder::PossibleValuesParser] or [`Arg::value_parser(["val1",
//! ...])`][crate::Arg::value_parser] for short.
//!
//! This allows you to specify the valid values for that argument. If the user does not use one of
//! those specific values, they will receive a graceful exit with error message informing them
//! of the mistake, and what the possible valid values are
//!
//! ```rust
#![doc = include_str!("../examples/tutorial_builder/04_01_possible.rs")]
//! ```
#![doc = include_str!("../examples/tutorial_builder/04_01_possible.md")]
//!
//! When enabling the [`derive` feature][crate::_features], you can use
//! [`ValueEnum`][crate::ValueEnum] to take care of the boiler plate for you, giving the same
//! results.
//!
//! ```rust
#![doc = include_str!("../examples/tutorial_builder/04_01_enum.rs")]
//! ```
#![doc = include_str!("../examples/tutorial_builder/04_01_enum.md")]
//!
//! ### Validated values
//!
//! More generally, you can validate and parse into any data type with [`Arg::value_parser`].
//!
//! ```rust
#![doc = include_str!("../examples/tutorial_builder/04_02_parse.rs")]
//! ```
#![doc = include_str!("../examples/tutorial_builder/04_02_parse.md")]
//!
//! A [custom parser][TypedValueParser] can be used to improve the error messages or provide additional validation:
//!
//! ```rust
#![doc = include_str!("../examples/tutorial_builder/04_02_validate.rs")]
//! ```
#![doc = include_str!("../examples/tutorial_builder/04_02_validate.md")]
//!
//! See [`Arg::value_parser`][crate::Arg::value_parser] for more details.
//!
//! ### Argument Relations
//!
//! You can declare dependencies or conflicts between [`Arg`][crate::Arg]s or even
//! [`ArgGroup`][crate::ArgGroup]s.
//!
//! [`ArgGroup`][crate::ArgGroup]s make it easier to declare relations instead of having to list
//! each individually, or when you want a rule to apply "any but not all" arguments.
//!
//! Perhaps the most common use of [`ArgGroup`][crate::ArgGroup]s is to require one and *only* one
//! argument to be present out of a given set. Imagine that you had multiple arguments, and you
//! want one of them to be required, but making all of them required isn't feasible because perhaps
//! they conflict with each other.
//!
//! ```rust
#![doc = include_str!("../examples/tutorial_builder/04_03_relations.rs")]
//! ```
#![doc = include_str!("../examples/tutorial_builder/04_03_relations.md")]
//!
//! ### Custom Validation
//!
//! As a last resort, you can create custom errors with the basics of clap's formatting.
//!
//! ```rust
#![doc = include_str!("../examples/tutorial_builder/04_04_custom.rs")]
//! ```
#![doc = include_str!("../examples/tutorial_builder/04_04_custom.md")]
//!
//! ## Testing
//!
//! clap reports most development errors as `debug_assert!`s. Rather than checking every
//! subcommand, you should have a test that calls
//! [`Command::debug_assert`][crate::Command::debug_assert]:
//! ```rust,no_run
#![doc = include_str!("../examples/tutorial_builder/05_01_assert.rs")]
//! ```
//!
//! ## Next Steps
//!
//! - [Cookbook][crate::_cookbook] for application-focused examples
//! - Explore more features in the [API reference][super]
//!
//! For support, see [Discussions](https://github.com/clap-rs/clap/discussions)
#![allow(unused_imports)]
use crate::builder::*;
24 changes: 0 additions & 24 deletions src/_tutorial/chapter_0.rs

This file was deleted.

31 changes: 0 additions & 31 deletions src/_tutorial/chapter_1.rs

This file was deleted.

87 changes: 0 additions & 87 deletions src/_tutorial/chapter_2.rs

This file was deleted.

84 changes: 0 additions & 84 deletions src/_tutorial/chapter_3.rs

This file was deleted.

15 changes: 0 additions & 15 deletions src/_tutorial/chapter_4.rs

This file was deleted.

12 changes: 0 additions & 12 deletions src/_tutorial/chapter_5.rs

This file was deleted.

36 changes: 0 additions & 36 deletions src/_tutorial/mod.rs

This file was deleted.

4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -6,8 +6,8 @@
//! > **Command Line Argument Parser for Rust**
//!
//! Quick Links:
//! - Derive [tutorial][_derive::_tutorial::chapter_0] and [reference][_derive]
//! - Builder [tutorial][_tutorial::chapter_0] and [reference](index.html)
//! - Derive [tutorial][_derive::_tutorial] and [reference][_derive]
//! - Builder [tutorial][_tutorial] and [reference](index.html)
//! - [Cookbook][_cookbook]
//! - [FAQ][_faq]
//! - [Discussions](https://github.com/clap-rs/clap/discussions)