Skip to content

Commit

Permalink
feat(parser): Convenient range value parsers
Browse files Browse the repository at this point in the history
There are several approaches with this
- `value_parser(N..M)`: creates an i64 range
- `value_parser(value_parser!(u16).range(10..))`: creates an u16 range
  that starts at 10
- `RangeI64ValueParser`: create whatever range you want

I was hoping to generalize `RangeI64ValueParser` for any source type,
not just i64, but ran into issues and decided to punt.  I chose `i64` as
the source type as it seemed the most general and didn't run into
portability issues like `isize`.

This is a step towards clap-rs#3199.  All that is left is for the derive to use
this.
  • Loading branch information
epage committed May 17, 2022
1 parent 6b0306d commit 63aa236
Show file tree
Hide file tree
Showing 3 changed files with 485 additions and 12 deletions.
9 changes: 5 additions & 4 deletions src/builder/arg.rs
Expand Up @@ -1010,6 +1010,7 @@ impl<'help> Arg<'help> {
/// - [`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] for numeric ranges
/// - [`ArgEnumValueParser`][crate::builder::ArgEnumValueParser] and [`PossibleValuesParser`][crate::builder::PossibleValuesParser] for static enumerated values
/// - or any other [`TypedValueParser`][crate::builder::TypedValueParser] implementation
///
Expand All @@ -1031,13 +1032,13 @@ impl<'help> Arg<'help> {
/// .arg(
/// clap::Arg::new("port")
/// .long("port")
/// .value_parser(clap::value_parser!(usize))
/// .value_parser(clap::value_parser!(u16).range(3000..))
/// .takes_value(true)
/// .required(true)
/// );
///
/// let m = cmd.try_get_matches_from_mut(
/// ["cmd", "--hostname", "rust-lang.org", "--port", "80"]
/// ["cmd", "--hostname", "rust-lang.org", "--port", "3001"]
/// ).unwrap();
///
/// let color: &String = m.get_one("color").unwrap().unwrap();
Expand All @@ -1046,8 +1047,8 @@ impl<'help> Arg<'help> {
/// let hostname: &String = m.get_one("hostname").unwrap().unwrap();
/// assert_eq!(hostname, "rust-lang.org");
///
/// let port: usize = *m.get_one("port").unwrap().unwrap();
/// assert_eq!(port, 80);
/// let port: u16 = *m.get_one("port").unwrap().unwrap();
/// assert_eq!(port, 3001);
/// ```
pub fn value_parser(mut self, parser: impl Into<super::ValueParser>) -> Self {
self.value_parser = Some(parser.into());
Expand Down
1 change: 1 addition & 0 deletions src/builder/mod.rs
Expand Up @@ -41,6 +41,7 @@ pub use value_parser::NonEmptyStringValueParser;
pub use value_parser::OsStringValueParser;
pub use value_parser::PathBufValueParser;
pub use value_parser::PossibleValuesParser;
pub use value_parser::RangedI64ValueParser;
pub use value_parser::StringValueParser;
pub use value_parser::TypedValueParser;
pub use value_parser::ValueParser;
Expand Down

0 comments on commit 63aa236

Please sign in to comment.