Skip to content

Commit

Permalink
fix(assert): Validate delimited defaults
Browse files Browse the repository at this point in the history
  • Loading branch information
epage committed Feb 28, 2022
1 parent bfeb751 commit 3f2a370
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 5 deletions.
6 changes: 6 additions & 0 deletions src/build/arg.rs
Expand Up @@ -4633,6 +4633,12 @@ impl<'help> Arg<'help> {
self.num_vals
}

/// Get the delimiter between multiple values
#[inline]
pub fn get_value_delimiter(&self) -> Option<char> {
self.val_delim
}

/// Get the index of this argument, if any
#[inline]
pub fn get_index(&self) -> Option<usize> {
Expand Down
25 changes: 23 additions & 2 deletions src/build/debug_asserts.rs
@@ -1,5 +1,7 @@
use std::cmp::Ordering;

use os_str_bytes::RawOsStr;

use crate::build::arg::ArgProvider;
use crate::mkeymap::KeyType;
use crate::util::Id;
Expand Down Expand Up @@ -686,7 +688,16 @@ fn assert_defaults<'d>(

if let Some(validator) = arg.validator.as_ref() {
let mut validator = validator.lock().unwrap();
if let Err(err) = validator(default_s) {
if let Some(delim) = arg.get_value_delimiter() {
for part in default_s.split(delim) {
if let Err(err) = validator(part) {
panic!(
"Argument `{}`'s {}={} failed validation: {}",
arg.name, field, part, err
);
}
}
} else if let Err(err) = validator(default_s) {
panic!(
"Argument `{}`'s {}={} failed validation: {}",
arg.name, field, default_s, err
Expand All @@ -697,7 +708,17 @@ fn assert_defaults<'d>(

if let Some(validator) = arg.validator_os.as_ref() {
let mut validator = validator.lock().unwrap();
if let Err(err) = validator(default_os) {
if let Some(delim) = arg.get_value_delimiter() {
let default_os = RawOsStr::new(default_os);
for part in default_os.split(delim) {
if let Err(err) = validator(&part.to_os_str()) {
panic!(
"Argument `{}`'s {}={:?} failed validation: {}",
arg.name, field, part, err
);
}
}
} else if let Err(err) = validator(default_os) {
panic!(
"Argument `{}`'s {}={:?} failed validation: {}",
arg.name, field, default_os, err
Expand Down
38 changes: 35 additions & 3 deletions tests/builder/default_vals.rs
Expand Up @@ -648,15 +648,47 @@ fn default_values_are_possible_values() {

#[cfg(debug_assertions)]
#[test]
#[should_panic = "Argument `arg`'s default_value=value failed validation: invalid digit found in string"]
fn default_values_are_valid() {
#[should_panic = "Argument `arg`'s default_value=one failed validation: invalid digit found in string"]
fn invalid_default_values() {
use clap::{Arg, Command};

let _ = Command::new("test")
.arg(
Arg::new("arg")
.validator(|val| val.parse::<u32>().map_err(|e| e.to_string()))
.default_value("value"),
.default_value("one"),
)
.try_get_matches();
}

#[test]
fn valid_delimited_default_values() {
use clap::{Arg, Command};

let _ = Command::new("test")
.arg(
Arg::new("arg")
.validator(|val| val.parse::<u32>().map_err(|e| e.to_string()))
.use_value_delimiter(true)
.require_value_delimiter(true)
.default_value("1,2,3"),
)
.try_get_matches();
}

#[cfg(debug_assertions)]
#[test]
#[should_panic = "Argument `arg`'s default_value=one failed validation: invalid digit found in string"]
fn invalid_delimited_default_values() {
use clap::{Arg, Command};

let _ = Command::new("test")
.arg(
Arg::new("arg")
.validator(|val| val.parse::<u32>().map_err(|e| e.to_string()))
.use_value_delimiter(true)
.require_value_delimiter(true)
.default_value("one,two"),
)
.try_get_matches();
}
Expand Down

0 comments on commit 3f2a370

Please sign in to comment.