From 99dfe7404a41cdfdec5d09352e8ec21af57be450 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 21 Sep 2022 11:02:06 -0500 Subject: [PATCH 1/2] docs(ref): Remove dead example This was missed in the migration to the reference being on docs.rs. Not feeling its worth finding a way to integrate it into the new structure. --- Cargo.toml | 5 ---- examples/derive_ref/custom-bool.md | 44 ------------------------------ examples/derive_ref/custom-bool.rs | 32 ---------------------- src/_derive/mod.rs | 1 - 4 files changed, 82 deletions(-) delete mode 100644 examples/derive_ref/custom-bool.md delete mode 100644 examples/derive_ref/custom-bool.rs diff --git a/Cargo.toml b/Cargo.toml index 38dd5bba..e70ed6a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -350,11 +350,6 @@ path = "examples/tutorial_derive/05_01_assert.rs" required-features = ["derive"] test = true -[[example]] -name = "custom-bool" -path = "examples/derive_ref/custom-bool.rs" -required-features = ["derive"] - [[example]] name = "interop_augment_args" path = "examples/derive_ref/augment_args.rs" diff --git a/examples/derive_ref/custom-bool.md b/examples/derive_ref/custom-bool.md deleted file mode 100644 index 04e3ff0c..00000000 --- a/examples/derive_ref/custom-bool.md +++ /dev/null @@ -1,44 +0,0 @@ -*Jump to [source](custom-bool.rs)* - -Example of overriding the magic `bool` behavior - -```console -$ custom-bool --help -A simple to use, efficient, and full-featured Command Line Argument Parser - -Usage: custom-bool[EXE] [OPTIONS] --foo - -Arguments: - [possible values: true, false] - -Options: - --foo [possible values: true, false] - --bar [default: false] - -h, --help Print help information - -V, --version Print version information - -$ custom-bool -? failed -error: The following required arguments were not provided: - --foo - - -Usage: custom-bool[EXE] --foo - -For more information try '--help' - -$ custom-bool --foo true false -[examples/derive_ref/custom-bool.rs:31] opt = Opt { - foo: true, - bar: false, - boom: false, -} - -$ custom-bool --foo true --bar true false -[examples/derive_ref/custom-bool.rs:31] opt = Opt { - foo: true, - bar: true, - boom: false, -} - -``` diff --git a/examples/derive_ref/custom-bool.rs b/examples/derive_ref/custom-bool.rs deleted file mode 100644 index ee2d6074..00000000 --- a/examples/derive_ref/custom-bool.rs +++ /dev/null @@ -1,32 +0,0 @@ -use clap::Parser; - -#[derive(Parser, Debug, PartialEq)] -#[command(author, version, about, long_about = None)] -struct Opt { - // Default parser for `Set` is FromStr::from_str. - // `impl FromStr for bool` parses `true` or `false` so this - // works as expected. - #[arg(long, action = clap::ArgAction::Set)] - foo: bool, - - // Of course, this could be done with an explicit parser function. - #[arg(long, action = clap::ArgAction::Set, value_parser = true_or_false, default_value_t)] - bar: bool, - - // `bool` can be positional only with explicit `action` annotation - #[arg(action = clap::ArgAction::Set)] - boom: bool, -} - -fn true_or_false(s: &str) -> Result { - match s { - "true" => Ok(true), - "false" => Ok(false), - _ => Err("expected `true` or `false`"), - } -} - -fn main() { - let opt = Opt::parse(); - dbg!(opt); -} diff --git a/src/_derive/mod.rs b/src/_derive/mod.rs index 6be1bfd1..2f5f97a0 100644 --- a/src/_derive/mod.rs +++ b/src/_derive/mod.rs @@ -265,7 +265,6 @@ //! //! Notes: //! - For custom type behavior, you can override the implied attributes/settings and/or set additional ones -//! - For example, see [custom-bool](./custom-bool.md) //! - `Option>` 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)` //! From 2bbb81f311fa379ae656a6e361e95b3e64eb433e Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 21 Sep 2022 11:06:33 -0500 Subject: [PATCH 2/2] 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 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/ --- src/_derive/_tutorial.rs | 7 ++++++- src/_derive/mod.rs | 22 ++++++++++++---------- src/_tutorial.rs | 4 ++++ src/builder/arg.rs | 21 +++++++++++---------- src/builder/value_parser.rs | 17 +++++++++++------ 5 files changed, 44 insertions(+), 27 deletions(-) diff --git a/src/_derive/_tutorial.rs b/src/_derive/_tutorial.rs index 3579596d..77f35024 100644 --- a/src/_derive/_tutorial.rs +++ b/src/_derive/_tutorial.rs @@ -154,9 +154,12 @@ //! //! ## 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 derive +//! For example, if you have arguments of specific values you want to test for, you can derive //! [`ValueEnum`][crate::ValueEnum]. //! //! 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")] //! +//! 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 diff --git a/src/_derive/mod.rs b/src/_derive/mod.rs index 2f5f97a0..a8b53815 100644 --- a/src/_derive/mod.rs +++ b/src/_derive/mod.rs @@ -186,7 +186,6 @@ //! - `value_parser [= ]`: [`Arg::value_parser`][crate::Arg::value_parser] //! - When not present: will auto-select an implementation based on the field type using //! [`value_parser!`][crate::value_parser!] -//! - To register a custom type's [`ValueParser`][crate::builder::ValueParser], implement [`ValueParserFactory`][crate::builder::ValueParserFactory] //! - `action [= ]`: [`Arg::action`][crate::Arg::action] //! - When not present: will auto-select an action based on the field type //! - `help = `: [`Arg::help`][crate::Arg::help] @@ -254,19 +253,22 @@ //! //! `clap` assumes some intent based on the type used: //! -//! | Type | Effect | Implies | -//! |---------------------|--------------------------------------|--------------------------------------------------------------------------| -//! | `bool` | flag | `.action(ArgAction::SetTrue) | -//! | `Option` | optional argument | `.action(ArgAction::Set).required(false)` | -//! | `Option>` | optional value for optional argument | `.action(ArgAction::Set).required(false).min_values(0).max_values(1)` | -//! | `T` | required argument | `.action(ArgAction::Set).required(!has_default)` | -//! | `Vec` | `0..` occurrences of argument | `.action(ArgAction::Append).required(false).multiple_occurrences(true)` | -//! | `Option>` | `0..` occurrences of argument | `.action(ArgAction::Append).required(false).multiple_occurrences(true)` | +//! | Type | Effect | Implies | +//! |---------------------|--------------------------------------|-------------------------------------------------------------| +//! | `bool` | flag | `.action(ArgAction::SetTrue) | +//! | `Option` | optional argument | `.action(ArgAction::Set).required(false)` | +//! | `Option>` | optional value for optional argument | `.action(ArgAction::Set).required(false).num_args(0..=1)` | +//! | `T` | required argument | `.action(ArgAction::Set).required(!has_default)` | +//! | `Vec` | `0..` occurrences of argument | `.action(ArgAction::Append).required(false).num_args(1..)` | +//! | `Option>` | `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: //! - For custom type behavior, you can override the implied attributes/settings and/or set additional ones //! - `Option>` 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 //! diff --git a/src/_tutorial.rs b/src/_tutorial.rs index cdb96ba1..67b77271 100644 --- a/src/_tutorial.rs +++ b/src/_tutorial.rs @@ -143,6 +143,8 @@ //! //! ## Validation //! +//! By default, arguments are assumed to be `String`s and only UTF-8 validation is performed. +//! //! ### Enumerated values //! //! 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")] //! +//! 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 diff --git a/src/builder/arg.rs b/src/builder/arg.rs index dce3794b..de92d3a3 100644 --- a/src/builder/arg.rs +++ b/src/builder/arg.rs @@ -867,21 +867,22 @@ impl Arg { 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 - /// [`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` + /// - `[&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]. /// - /// 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 /// # use clap::ArgAction; /// let mut cmd = clap::Command::new("raw") diff --git a/src/builder/value_parser.rs b/src/builder/value_parser.rs index 8fa6cc4d..c5b97061 100644 --- a/src/builder/value_parser.rs +++ b/src/builder/value_parser.rs @@ -73,9 +73,8 @@ enum ValueParserInner { impl ValueParser { /// Custom parser for argument values /// - /// To create a custom parser, see [`TypedValueParser`] - /// - /// Pre-existing implementations include: + /// Pre-existing [`TypedValueParser`] implementations include: + /// - `Fn(&str) -> Result` /// - [`EnumValueParser`] and [`PossibleValuesParser`] for static enumerated values /// - [`BoolishValueParser`] and [`FalseyValueParser`] for alternative `bool` implementations /// - [`RangedI64ValueParser`] and [`RangedU64ValueParser`] @@ -989,7 +988,8 @@ impl Default for EnumValueP /// Verify the value is from an enumerated set of [`PossibleValue`][crate::builder::PossibleValue]. /// /// See also: -/// - [`EnumValueParser`] +/// - [`EnumValueParser`] for directly supporting `enum`s +/// - [`TypedValueParser::map`] for adapting values to a more specialized type /// /// # Example /// @@ -2083,7 +2083,12 @@ pub mod via_prelude { /// 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 /// @@ -2104,7 +2109,7 @@ pub mod via_prelude { /// assert_eq!(port, Path::new("file.txt")); /// ``` /// -/// Supported types: +/// Example mappings: /// ```rust /// // Built-in types /// let parser = clap::value_parser!(String);