Skip to content

Commit

Permalink
Merge pull request #266 from dtolnay/wildcard
Browse files Browse the repository at this point in the history
Improve error on comma after wildcard
  • Loading branch information
dtolnay committed Feb 4, 2022
2 parents 43639e8 + cf82eb0 commit 3365701
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 8 deletions.
8 changes: 8 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub(crate) enum ErrorKind {
Overflow(Position),
EmptySegment(Position),
IllegalCharacter(Position),
CommaAfterWildcard(char),
UnexpectedAfterWildcard,
ExcessiveComparators,
}
Expand Down Expand Up @@ -58,6 +59,13 @@ impl Display for Error {
ErrorKind::IllegalCharacter(pos) => {
write!(formatter, "unexpected character in {}", pos)
}
ErrorKind::CommaAfterWildcard(ch) => {
write!(
formatter,
"wildcard req ({}) must be the only comparator in the version req",
ch,
)
}
ErrorKind::UnexpectedAfterWildcard => {
formatter.write_str("unexpected character after wildcard in version req")
}
Expand Down
19 changes: 11 additions & 8 deletions src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,17 @@ impl FromStr for VersionReq {

fn from_str(text: &str) -> Result<Self, Self::Err> {
let text = text.trim_start_matches(' ');
if let Some(text) = wildcard(text) {
if text.trim_start_matches(' ').is_empty() {
if let Some((ch, text)) = wildcard(text) {
let rest = text.trim_start_matches(' ');
if rest.is_empty() {
#[cfg(not(no_const_vec_new))]
return Ok(VersionReq::STAR);
#[cfg(no_const_vec_new)] // rustc <1.39
return Ok(VersionReq {
comparators: Vec::new(),
});
} else if rest.starts_with(',') {
return Err(Error::new(ErrorKind::CommaAfterWildcard(ch)));
} else {
return Err(Error::new(ErrorKind::UnexpectedAfterWildcard));
}
Expand Down Expand Up @@ -181,13 +184,13 @@ fn numeric_identifier(input: &str, pos: Position) -> Result<(u64, &str), Error>
}
}

fn wildcard(input: &str) -> Option<&str> {
fn wildcard(input: &str) -> Option<(char, &str)> {
if let Some(rest) = input.strip_prefix('*') {
Some(rest)
Some(('*', rest))
} else if let Some(rest) = input.strip_prefix('x') {
Some(rest)
Some(('x', rest))
} else if let Some(rest) = input.strip_prefix('X') {
Some(rest)
Some(('X', rest))
} else {
None
}
Expand Down Expand Up @@ -293,7 +296,7 @@ fn comparator(input: &str) -> Result<(Comparator, Position, &str), Error> {

let (minor, text) = if let Some(text) = text.strip_prefix('.') {
pos = Position::Minor;
if let Some(text) = wildcard(text) {
if let Some((_, text)) = wildcard(text) {
has_wildcard = true;
if default_op {
op = Op::Wildcard;
Expand All @@ -309,7 +312,7 @@ fn comparator(input: &str) -> Result<(Comparator, Position, &str), Error> {

let (patch, text) = if let Some(text) = text.strip_prefix('.') {
pos = Position::Patch;
if let Some(text) = wildcard(text) {
if let Some((_, text)) = wildcard(text) {
if default_op {
op = Op::Wildcard;
}
Expand Down
15 changes: 15 additions & 0 deletions tests/test_version_req.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,3 +413,18 @@ fn test_leading_digit_in_pre_and_build() {
req(&format!("{} 1.2.3-1a-1a+1a-1a-1a", op));
}
}

#[test]
fn test_wildcard_and_another() {
let err = req_err("*, 0.20.0-any");
assert_to_string(
err,
"wildcard req (*) must be the only comparator in the version req",
);

let err = req_err("0.20.0-any, *");
assert_to_string(
err,
"unexpected character '*' while parsing major version number",
);
}

0 comments on commit 3365701

Please sign in to comment.