Skip to content

Commit 6696513

Browse files
authored
Merge pull request #4796 from epage/lex
fix(lex): Allow reporting errors for non-UTF8 longs
2 parents a916daa + ea4dada commit 6696513

File tree

4 files changed

+34
-21
lines changed

4 files changed

+34
-21
lines changed

clap_builder/src/parser/parser.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,7 @@ impl<'cmd> Parser<'cmd> {
720720
fn parse_long_arg(
721721
&mut self,
722722
matcher: &mut ArgMatcher,
723-
long_arg: &str,
723+
long_arg: Result<&str, &OsStr>,
724724
long_value: Option<&OsStr>,
725725
parse_state: &ParseState,
726726
pos_counter: usize,
@@ -738,6 +738,14 @@ impl<'cmd> Parser<'cmd> {
738738
}
739739

740740
debug!("Parser::parse_long_arg: Does it contain '='...");
741+
let long_arg = match long_arg {
742+
Ok(long_arg) => long_arg,
743+
Err(long_arg_os) => {
744+
return Ok(ParseResult::NoMatchingArg {
745+
arg: long_arg_os.to_string_lossy().into_owned(),
746+
})
747+
}
748+
};
741749
if long_arg.is_empty() {
742750
debug_assert!(
743751
long_value.is_some(),

clap_complete/src/dynamic.rs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -368,23 +368,28 @@ complete OPTIONS -F _clap_complete_NAME EXECUTABLES
368368

369369
if !is_escaped {
370370
if let Some((flag, value)) = arg.to_long() {
371-
if let Some(value) = value {
372-
if let Some(arg) = cmd.get_arguments().find(|a| a.get_long() == Some(flag)) {
371+
if let Ok(flag) = flag {
372+
if let Some(value) = value {
373+
if let Some(arg) = cmd.get_arguments().find(|a| a.get_long() == Some(flag))
374+
{
375+
completions.extend(
376+
complete_arg_value(value.to_str().ok_or(value), arg, current_dir)
377+
.into_iter()
378+
.map(|os| {
379+
// HACK: Need better `OsStr` manipulation
380+
format!("--{}={}", flag, os.to_string_lossy()).into()
381+
}),
382+
)
383+
}
384+
} else {
373385
completions.extend(
374-
complete_arg_value(value.to_str().ok_or(value), arg, current_dir)
386+
crate::generator::utils::longs_and_visible_aliases(cmd)
375387
.into_iter()
376-
.map(|os| {
377-
// HACK: Need better `OsStr` manipulation
378-
format!("--{}={}", flag, os.to_string_lossy()).into()
388+
.filter_map(|f| {
389+
f.starts_with(flag).then(|| format!("--{}", f).into())
379390
}),
380-
)
391+
);
381392
}
382-
} else {
383-
completions.extend(
384-
crate::generator::utils::longs_and_visible_aliases(cmd)
385-
.into_iter()
386-
.filter_map(|f| f.starts_with(flag).then(|| format!("--{}", f).into())),
387-
);
388393
}
389394
} else if arg.is_escape() || arg.is_stdio() || arg.is_empty() {
390395
// HACK: Assuming knowledge of is_escape / is_stdio

clap_lex/src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,13 @@
6565
//! args.paths.push(PathBuf::from("-"));
6666
//! } else if let Some((long, value)) = arg.to_long() {
6767
//! match long {
68-
//! "verbose" => {
68+
//! Ok("verbose") => {
6969
//! if let Some(value) = value {
7070
//! return Err(format!("`--verbose` does not take a value, got `{:?}`", value).into());
7171
//! }
7272
//! args.verbosity += 1;
7373
//! }
74-
//! "color" => {
74+
//! Ok("color") => {
7575
//! args.color = Color::parse(value)?;
7676
//! }
7777
//! _ => {
@@ -308,7 +308,7 @@ impl<'s> ParsedArg<'s> {
308308
}
309309

310310
/// Treat as a long-flag
311-
pub fn to_long(&self) -> Option<(&str, Option<&OsStr>)> {
311+
pub fn to_long(&self) -> Option<(Result<&str, &OsStr>, Option<&OsStr>)> {
312312
let raw = self.inner;
313313
let remainder = raw.strip_prefix("--")?;
314314
if remainder.is_empty() {
@@ -321,7 +321,7 @@ impl<'s> ParsedArg<'s> {
321321
} else {
322322
(remainder, None)
323323
};
324-
let flag = flag.to_str()?;
324+
let flag = flag.to_str().ok_or(flag);
325325
Some((flag, value))
326326
}
327327

clap_lex/tests/parsed.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ fn to_long_no_value() {
3636
assert!(next.is_long());
3737

3838
let (key, value) = next.to_long().unwrap();
39-
assert_eq!(key, "long");
39+
assert_eq!(key, Ok("long"));
4040
assert_eq!(value, None);
4141
}
4242

@@ -50,7 +50,7 @@ fn to_long_with_empty_value() {
5050
assert!(next.is_long());
5151

5252
let (key, value) = next.to_long().unwrap();
53-
assert_eq!(key, "long");
53+
assert_eq!(key, Ok("long"));
5454
assert_eq!(value, Some(OsStr::new("")));
5555
}
5656

@@ -64,7 +64,7 @@ fn to_long_with_value() {
6464
assert!(next.is_long());
6565

6666
let (key, value) = next.to_long().unwrap();
67-
assert_eq!(key, "long");
67+
assert_eq!(key, Ok("long"));
6868
assert_eq!(value, Some(OsStr::new("hello")));
6969
}
7070

0 commit comments

Comments
 (0)