docs: Clarify value parser

Things that tripped up a user
- Derive reference was misunderstood to say that the only alternative to
  the built-in value parser behavior was to implement
  `ValueParserFactory`
  - We now delegate to `value_parser!`s docs any talk of integrating
    into it (it should have been a subbullet of "not present" anyways)
- `value_parser!` relies too much on the example to demonstrate behavior
  when the user will likely make the determination of whether its
  relevant before then
  - We are now more upfront what type mappings are supported
- Too many steps to find all information
  - For example, a user needs to look at `TypedValueParser`
    implementations, `ValueParserFactory` implementations, and `From<T>
    for ValueParser` implementations to understand what all can be used
  - We are now more upfront with a lot of this information at the entry
    points the user is most likely to look at

In addition, I did an audit of the docs to make sure they were updated
for us only supporting the new behavior and all of the new APIs.

See https://www.reddit.com/r/rust/comments/xjlie4/preannouncing_clap_40_a_rust_cli_argument_parser/ip9kzf1/
This commit is contained in:
Ed Page 2022-09-21 11:06:33 -05:00
parent 99dfe7404a
commit 2bbb81f311
5 changed files with 44 additions and 27 deletions

View file

@ -154,9 +154,12 @@
//! //!
//! ## Validation //! ## 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 //! ### Enumerated values
//! //!
//! If you have arguments of specific values you want to test for, you can derive //! For example, if you have arguments of specific values you want to test for, you can derive
//! [`ValueEnum`][crate::ValueEnum]. //! [`ValueEnum`][crate::ValueEnum].
//! //!
//! This allows you specify the valid values for that argument. If the user does not use one of //! This allows you specify the valid values for that argument. If the user does not use one of
@ -184,6 +187,8 @@
//! ``` //! ```
#![doc = include_str!("../../examples/tutorial_derive/04_02_validate.md")] #![doc = include_str!("../../examples/tutorial_derive/04_02_validate.md")]
//! //!
//! See [`Arg::value_parser`][crate::Arg::value_parser] for more details.
//!
//! ### Argument Relations //! ### Argument Relations
//! //!
//! You can declare dependencies or conflicts between [`Arg`][crate::Arg]s or even //! You can declare dependencies or conflicts between [`Arg`][crate::Arg]s or even

View file

@ -186,7 +186,6 @@
//! - `value_parser [= <expr>]`: [`Arg::value_parser`][crate::Arg::value_parser] //! - `value_parser [= <expr>]`: [`Arg::value_parser`][crate::Arg::value_parser]
//! - When not present: will auto-select an implementation based on the field type using //! - When not present: will auto-select an implementation based on the field type using
//! [`value_parser!`][crate::value_parser!] //! [`value_parser!`][crate::value_parser!]
//! - To register a custom type's [`ValueParser`][crate::builder::ValueParser], implement [`ValueParserFactory`][crate::builder::ValueParserFactory]
//! - `action [= <expr>]`: [`Arg::action`][crate::Arg::action] //! - `action [= <expr>]`: [`Arg::action`][crate::Arg::action]
//! - When not present: will auto-select an action based on the field type //! - When not present: will auto-select an action based on the field type
//! - `help = <expr>`: [`Arg::help`][crate::Arg::help] //! - `help = <expr>`: [`Arg::help`][crate::Arg::help]
@ -254,19 +253,22 @@
//! //!
//! `clap` assumes some intent based on the type used: //! `clap` assumes some intent based on the type used:
//! //!
//! | Type | Effect | Implies | //! | Type | Effect | Implies |
//! |---------------------|--------------------------------------|--------------------------------------------------------------------------| //! |---------------------|--------------------------------------|-------------------------------------------------------------|
//! | `bool` | flag | `.action(ArgAction::SetTrue) | //! | `bool` | flag | `.action(ArgAction::SetTrue) |
//! | `Option<T>` | optional argument | `.action(ArgAction::Set).required(false)` | //! | `Option<T>` | optional argument | `.action(ArgAction::Set).required(false)` |
//! | `Option<Option<T>>` | optional value for optional argument | `.action(ArgAction::Set).required(false).min_values(0).max_values(1)` | //! | `Option<Option<T>>` | optional value for optional argument | `.action(ArgAction::Set).required(false).num_args(0..=1)` |
//! | `T` | required argument | `.action(ArgAction::Set).required(!has_default)` | //! | `T` | required argument | `.action(ArgAction::Set).required(!has_default)` |
//! | `Vec<T>` | `0..` occurrences of argument | `.action(ArgAction::Append).required(false).multiple_occurrences(true)` | //! | `Vec<T>` | `0..` occurrences of argument | `.action(ArgAction::Append).required(false).num_args(1..)` |
//! | `Option<Vec<T>>` | `0..` occurrences of argument | `.action(ArgAction::Append).required(false).multiple_occurrences(true)` | //! | `Option<Vec<T>>` | `0..` occurrences of argument | `.action(ArgAction::Append).required(false).num_args(1..)` |
//!
//! In addition, [`.value_parser(value_parser!(T))`][crate::value_parser!] is called for each
//! field.
//! //!
//! Notes: //! Notes:
//! - For custom type behavior, you can override the implied attributes/settings and/or set additional ones //! - For custom type behavior, you can override the implied attributes/settings and/or set additional ones
//! - `Option<Vec<T>>` will be `None` instead of `vec![]` if no arguments are provided. //! - `Option<Vec<T>>` will be `None` instead of `vec![]` if no arguments are provided.
//! - This gives the user some flexibility in designing their argument, like with `min_values(0)` //! - This gives the user some flexibility in designing their argument, like with `num_args(0..)`
//! //!
//! ## Doc Comments //! ## Doc Comments
//! //!

View file

@ -143,6 +143,8 @@
//! //!
//! ## Validation //! ## Validation
//! //!
//! By default, arguments are assumed to be `String`s and only UTF-8 validation is performed.
//!
//! ### Enumerated values //! ### Enumerated values
//! //!
//! If you have arguments of specific values you want to test for, you can use the //! If you have arguments of specific values you want to test for, you can use the
@ -183,6 +185,8 @@
//! ``` //! ```
#![doc = include_str!("../examples/tutorial_builder/04_02_validate.md")] #![doc = include_str!("../examples/tutorial_builder/04_02_validate.md")]
//! //!
//! See [`Arg::value_parser`][crate::Arg::value_parser] for more details.
//!
//! ### Argument Relations //! ### Argument Relations
//! //!
//! You can declare dependencies or conflicts between [`Arg`][crate::Arg]s or even //! You can declare dependencies or conflicts between [`Arg`][crate::Arg]s or even

View file

@ -867,21 +867,22 @@ impl Arg {
self self
} }
/// Specify the type of the argument. /// Specify the typed behavior of the argument.
/// ///
/// This allows parsing and validating a value before storing it into /// This allows parsing and validating a value before storing it into
/// [`ArgMatches`][crate::ArgMatches]. /// [`ArgMatches`][crate::ArgMatches] as the given type.
///
/// Possible value parsers include:
/// - [`value_parser!(T)`][crate::value_parser!] for auto-selecting a value parser for a given type
/// - Or [range expressions like `0..=1`][std::ops::RangeBounds] as a shorthand for [`RangedI64ValueParser`][crate::builder::RangedI64ValueParser]
/// - `Fn(&str) -> Result<T, E>`
/// - `[&str]` and [`PossibleValuesParser`][crate::builder::PossibleValuesParser] for static enumerated values
/// - [`BoolishValueParser`][crate::builder::BoolishValueParser], and [`FalseyValueParser`][crate::builder::FalseyValueParser] for alternative `bool` implementations
/// - [`NonEmptyStringValueParser`][crate::builder::NonEmptyStringValueParser] for basic validation for strings
/// - or any other [`TypedValueParser`][crate::builder::TypedValueParser] implementation
/// ///
/// The default value is [`ValueParser::string`][crate::builder::ValueParser::string]. /// The default value is [`ValueParser::string`][crate::builder::ValueParser::string].
/// ///
/// See also
/// - [`value_parser!`][crate::value_parser!] for auto-selecting a value parser for a given type
/// - [`BoolishValueParser`][crate::builder::BoolishValueParser], and [`FalseyValueParser`][crate::builder::FalseyValueParser] for alternative `bool` implementations
/// - [`NonEmptyStringValueParser`][crate::builder::NonEmptyStringValueParser] for basic validation for strings
/// - [`RangedI64ValueParser`][crate::builder::RangedI64ValueParser] and [`RangedU64ValueParser`][crate::builder::RangedU64ValueParser] for numeric ranges
/// - [`EnumValueParser`][crate::builder::EnumValueParser] and [`PossibleValuesParser`][crate::builder::PossibleValuesParser] for static enumerated values
/// - or any other [`TypedValueParser`][crate::builder::TypedValueParser] implementation
///
/// ```rust /// ```rust
/// # use clap::ArgAction; /// # use clap::ArgAction;
/// let mut cmd = clap::Command::new("raw") /// let mut cmd = clap::Command::new("raw")

View file

@ -73,9 +73,8 @@ enum ValueParserInner {
impl ValueParser { impl ValueParser {
/// Custom parser for argument values /// Custom parser for argument values
/// ///
/// To create a custom parser, see [`TypedValueParser`] /// Pre-existing [`TypedValueParser`] implementations include:
/// /// - `Fn(&str) -> Result<T, E>`
/// Pre-existing implementations include:
/// - [`EnumValueParser`] and [`PossibleValuesParser`] for static enumerated values /// - [`EnumValueParser`] and [`PossibleValuesParser`] for static enumerated values
/// - [`BoolishValueParser`] and [`FalseyValueParser`] for alternative `bool` implementations /// - [`BoolishValueParser`] and [`FalseyValueParser`] for alternative `bool` implementations
/// - [`RangedI64ValueParser`] and [`RangedU64ValueParser`] /// - [`RangedI64ValueParser`] and [`RangedU64ValueParser`]
@ -989,7 +988,8 @@ impl<E: crate::ValueEnum + Clone + Send + Sync + 'static> Default for EnumValueP
/// Verify the value is from an enumerated set of [`PossibleValue`][crate::builder::PossibleValue]. /// Verify the value is from an enumerated set of [`PossibleValue`][crate::builder::PossibleValue].
/// ///
/// See also: /// See also:
/// - [`EnumValueParser`] /// - [`EnumValueParser`] for directly supporting `enum`s
/// - [`TypedValueParser::map`] for adapting values to a more specialized type
/// ///
/// # Example /// # Example
/// ///
@ -2083,7 +2083,12 @@ pub mod via_prelude {
/// Select a [`ValueParser`] implementation from the intended type /// Select a [`ValueParser`] implementation from the intended type
/// ///
/// To register a custom type with this macro, implement [`ValueParserFactory`]. /// Supported types
/// - [`ValueParserFactory` types][ValueParserFactory], including
/// - [Native types][ValueParser]: `bool`, `String`, `OsString`, `PathBuf`
/// - [Ranged numeric types][RangedI64ValueParser]: `u8`, `i8`, `u16`, `i16, `u32`, `i32`, `u64`, `i64`
/// - [`ValueEnum` types][crate::ValueEnum]
/// - [`FromStr` types][std::str::FromStr], including usize, isize
/// ///
/// # Example /// # Example
/// ///
@ -2104,7 +2109,7 @@ pub mod via_prelude {
/// assert_eq!(port, Path::new("file.txt")); /// assert_eq!(port, Path::new("file.txt"));
/// ``` /// ```
/// ///
/// Supported types: /// Example mappings:
/// ```rust /// ```rust
/// // Built-in types /// // Built-in types
/// let parser = clap::value_parser!(String); /// let parser = clap::value_parser!(String);