Skip to content

Commit

Permalink
Implement OnlyOnce check and reporting
Browse files Browse the repository at this point in the history
  • Loading branch information
lu-zero committed Dec 27, 2024
1 parent da982b7 commit f0018ee
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 2 deletions.
11 changes: 9 additions & 2 deletions bpaf_core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ impl Message {
// when handle gets thrown out
Self::Killed => true,
Self::Conflicts { .. } => false,
Self::OnlyOnce { .. } => false,
Self::Unexpected => false,
Self::ParseFailed(..) => false,
Self::ArgNeedsValue { .. } => false,
Expand Down Expand Up @@ -186,8 +187,10 @@ pub(crate) enum Message {
// /// Expected one or more items in the scope, got someting else if any
// Expected(Vec<Item>, Option<usize>),
//
// /// Parameter is accepted but only once
// OnlyOnce(/* winner */ usize, usize),
/// Parameter is accepted but only once
OnlyOnce {
name: Name<'static>,
},
}

impl Message {
Expand Down Expand Up @@ -229,6 +232,10 @@ impl Message {
res,
"{name} wants a value {meta}, got {val}, try using {name}={val}"
)?,
Message::OnlyOnce { name } => write!(
res,
"argument `{name}` cannot be used multiple times in this context"
)?,
}
Ok(res)
}
Expand Down
20 changes: 20 additions & 0 deletions bpaf_core/src/visitor/explain_unparsed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ impl<'a> ExplainUnparsed<'a> {
if let Some(err) = self.is_in_conflict(&parsed, name.as_ref()) {
return err;
}
if let Some(err) = self.is_redundant(&parsed, name.as_ref()) {
return err;
}
}

// Suggestions I'd like to make
Expand Down Expand Up @@ -127,6 +130,23 @@ impl<'a> ExplainUnparsed<'a> {
}
None
}

fn is_redundant(&self, parsed: &[Name], unparsed: Name) -> Option<Error> {
let unparsed_info = self.all_names.get(&unparsed)?;
if unparsed_info.in_many {
return None;
}

if parsed.contains(&unparsed) {
return Some(Error {
message: crate::error::Message::OnlyOnce {
name: unparsed.to_owned(),
},
});
}

None
}
}

impl<'a> Visitor<'a> for ExplainUnparsed<'a> {
Expand Down
8 changes: 8 additions & 0 deletions bpaf_core/tests/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,4 +339,12 @@ fn used_only_once_is_more_important_error() {
err,
"argument `--sort` cannot be used multiple times in this context"
);
let err = opts
.run_inner(&["--sort", "--filter", "--sort", "--filter"])
.unwrap_err()
.unwrap_stderr();
assert_eq!(
err,
"argument `--sort` cannot be used multiple times in this context"
);
}

0 comments on commit f0018ee

Please sign in to comment.