1844: Fix a couple of very minor bugs r=pksunkara a=CreepySkeleton



Co-authored-by: CreepySkeleton <creepy-skeleton@yandex.ru>
This commit is contained in:
bors[bot] 2020-04-20 16:27:34 +00:00 committed by GitHub
commit 0a3921f554
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 12 deletions

View file

@ -367,7 +367,8 @@ where
self.app.args.insert_key(k, i); self.app.args.insert_key(k, i);
} }
debug_assert!(self._verify_positionals()); #[cfg(debug_assertions)]
self._verify_positionals();
// Set the LowIndexMultiple flag if required // Set the LowIndexMultiple flag if required
if positionals!(self.app).any(|a| { if positionals!(self.app).any(|a| {
@ -1214,8 +1215,8 @@ where
p[0].as_bytes(), p[0].as_bytes(),
p[1].as_bytes() p[1].as_bytes()
); );
let i = p[0].as_bytes().len() + 1; let i = p[0].as_bytes().len() + c.len_utf8();
let val = if !p[1].as_bytes().is_empty() { let val = if !p[1].is_empty() {
debugln!( debugln!(
"Parser::parse_short_arg:iter:{}: val={:?} (bytes), val={:?} (ascii)", "Parser::parse_short_arg:iter:{}: val={:?} (bytes), val={:?} (ascii)",
c, c,
@ -1228,11 +1229,10 @@ where
}; };
// Default to "we're expecting a value later" // Default to "we're expecting a value later"
let ret = self.parse_opt(val, opt, false, matcher)?; return self.parse_opt(val, opt, false, matcher);
return Ok(ret);
} else { } else {
let arg = format!("-{}", c); let arg = format!("-{}", c);
return Err(ClapError::unknown_argument( return Err(ClapError::unknown_argument(
&*arg, &*arg,
None, None,
@ -1262,7 +1262,7 @@ where
debug!("Parser::parse_opt; Checking for val..."); debug!("Parser::parse_opt; Checking for val...");
if let Some(fv) = val { if let Some(fv) = val {
has_eq = fv.starts_with(&[b'=']) || had_eq; has_eq = fv.starts_with(&[b'=']) || had_eq;
let v = fv.trim_start_matches(b'='); let v = fv.trim_start_n_matches(1, b'=');
if !empty_vals && (v.is_empty() || (needs_eq && !has_eq)) { if !empty_vals && (v.is_empty() || (needs_eq && !has_eq)) {
sdebugln!("Found Empty - Error"); sdebugln!("Found Empty - Error");
return Err(ClapError::empty_value( return Err(ClapError::empty_value(

View file

@ -15,6 +15,7 @@ pub(crate) trait OsStrExt2 {
fn split_at_byte(&self, b: u8) -> (&OsStr, &OsStr); fn split_at_byte(&self, b: u8) -> (&OsStr, &OsStr);
fn split_at(&self, i: usize) -> (&OsStr, &OsStr); fn split_at(&self, i: usize) -> (&OsStr, &OsStr);
fn trim_start_matches(&self, b: u8) -> &OsStr; fn trim_start_matches(&self, b: u8) -> &OsStr;
fn trim_start_n_matches(&self, n: usize, ch: u8) -> &OsStr;
fn contains_byte(&self, b: u8) -> bool; fn contains_byte(&self, b: u8) -> bool;
fn split(&self, b: u8) -> OsSplit; fn split(&self, b: u8) -> OsSplit;
} }
@ -50,14 +51,11 @@ impl OsStrExt2 for OsStr {
if b == &byte { if b == &byte {
return ( return (
OsStr::from_bytes(&self.as_bytes()[..i]), OsStr::from_bytes(&self.as_bytes()[..i]),
OsStr::from_bytes(&self.as_bytes()[i + 1..]), OsStr::from_bytes(&self.as_bytes()[i..]),
); );
} }
} }
( (&*self, OsStr::from_bytes(&[]))
&*self,
OsStr::from_bytes(&self.as_bytes()[self.len()..self.len()]),
)
} }
fn trim_start_matches(&self, byte: u8) -> &OsStr { fn trim_start_matches(&self, byte: u8) -> &OsStr {
@ -75,6 +73,22 @@ impl OsStrExt2 for OsStr {
&*self &*self
} }
// Like `trim_start_matches`, but trims no more than `n` matches
#[inline]
fn trim_start_n_matches(&self, n: usize, ch: u8) -> &OsStr {
let i = self
.as_bytes()
.iter()
.take(n)
.take_while(|c| **c == ch)
.enumerate()
.last()
.map(|(i, _)| i + 1)
.unwrap_or(0);
self.split_at(i).1
}
fn split_at(&self, i: usize) -> (&OsStr, &OsStr) { fn split_at(&self, i: usize) -> (&OsStr, &OsStr) {
( (
OsStr::from_bytes(&self.as_bytes()[..i]), OsStr::from_bytes(&self.as_bytes()[..i]),

View file

@ -483,3 +483,30 @@ fn issue_1073_suboptimal_flag_suggestion() {
true true
)); ));
} }
#[test]
fn short_non_ascii_no_space() {
let matches = App::new("app")
.arg("<opt> -磨 <opt>")
.get_matches_from(&["test", "-磨VALUE"]);
assert_eq!("VALUE", matches.value_of("opt").unwrap());
}
#[test]
fn short_eq_val_starts_with_eq() {
let matches = App::new("app")
.arg("<opt> -f <opt>")
.get_matches_from(&["test", "-f==value"]);
assert_eq!("=value", matches.value_of("opt").unwrap());
}
#[test]
fn long_eq_val_starts_with_eq() {
let matches = App::new("app")
.arg("<opt> --foo <opt>")
.get_matches_from(&["test", "--foo==value"]);
assert_eq!("=value", matches.value_of("opt").unwrap());
}