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 ba244b2
Show file tree
Hide file tree
Showing 2 changed files with 31 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
22 changes: 22 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,25 @@ 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;
}
for p in parsed {
let Some(parsed) = self.all_names.get(p) else {
continue;
};
if !parsed.in_many {
return Some(Error {
message: crate::error::Message::OnlyOnce {
name: unparsed.to_owned(),
},
});
}
}
None
}
}

impl<'a> Visitor<'a> for ExplainUnparsed<'a> {
Expand Down

0 comments on commit ba244b2

Please sign in to comment.