mirror of
https://github.com/clap-rs/clap
synced 2025-03-04 07:17:26 +00:00
Merge pull request #3521 from epage/assert
fix(assert): Validate delimited defaults
This commit is contained in:
commit
fce7796c1d
3 changed files with 64 additions and 5 deletions
|
@ -4633,6 +4633,12 @@ impl<'help> Arg<'help> {
|
||||||
self.num_vals
|
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
|
/// Get the index of this argument, if any
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_index(&self) -> Option<usize> {
|
pub fn get_index(&self) -> Option<usize> {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
|
use os_str_bytes::RawOsStr;
|
||||||
|
|
||||||
use crate::build::arg::ArgProvider;
|
use crate::build::arg::ArgProvider;
|
||||||
use crate::mkeymap::KeyType;
|
use crate::mkeymap::KeyType;
|
||||||
use crate::util::Id;
|
use crate::util::Id;
|
||||||
|
@ -686,7 +688,16 @@ fn assert_defaults<'d>(
|
||||||
|
|
||||||
if let Some(validator) = arg.validator.as_ref() {
|
if let Some(validator) = arg.validator.as_ref() {
|
||||||
let mut validator = validator.lock().unwrap();
|
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!(
|
panic!(
|
||||||
"Argument `{}`'s {}={} failed validation: {}",
|
"Argument `{}`'s {}={} failed validation: {}",
|
||||||
arg.name, field, default_s, err
|
arg.name, field, default_s, err
|
||||||
|
@ -697,7 +708,17 @@ fn assert_defaults<'d>(
|
||||||
|
|
||||||
if let Some(validator) = arg.validator_os.as_ref() {
|
if let Some(validator) = arg.validator_os.as_ref() {
|
||||||
let mut validator = validator.lock().unwrap();
|
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!(
|
panic!(
|
||||||
"Argument `{}`'s {}={:?} failed validation: {}",
|
"Argument `{}`'s {}={:?} failed validation: {}",
|
||||||
arg.name, field, default_os, err
|
arg.name, field, default_os, err
|
||||||
|
|
|
@ -648,15 +648,47 @@ fn default_values_are_possible_values() {
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic = "Argument `arg`'s default_value=value failed validation: invalid digit found in string"]
|
#[should_panic = "Argument `arg`'s default_value=one failed validation: invalid digit found in string"]
|
||||||
fn default_values_are_valid() {
|
fn invalid_default_values() {
|
||||||
use clap::{Arg, Command};
|
use clap::{Arg, Command};
|
||||||
|
|
||||||
let _ = Command::new("test")
|
let _ = Command::new("test")
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("arg")
|
Arg::new("arg")
|
||||||
.validator(|val| val.parse::<u32>().map_err(|e| e.to_string()))
|
.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();
|
.try_get_matches();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue