Skip to content

Commit

Permalink
Ugrade winnow to 0.6.5 (#55)
Browse files Browse the repository at this point in the history
  • Loading branch information
zharinov authored Mar 1, 2024
1 parent b98a03d commit 88fccad
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 52 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ edition = "2021"
license = "MIT"

[dependencies]
winnow = "0.4.7"
winnow = "0.6.5"

[dev-dependencies]
rstest = "0.18.2"
Expand Down
36 changes: 14 additions & 22 deletions src/maven/version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
use std::cmp::Ordering;

use winnow::ascii::digit1;
use winnow::combinator::{alt, eof, repeat};
use winnow::combinator::{alt, repeat};
use winnow::token::take_while;
use winnow::{IResult, Parser};
use winnow::{PResult, Parser};

#[derive(Debug)]
enum RawToken<'a> {
Expand Down Expand Up @@ -33,7 +33,7 @@ struct Token {
value: TokenValue,
}

fn number(input: &str) -> IResult<&str, RawToken> {
fn number<'a>(input: &mut &'a str) -> PResult<RawToken<'a>> {
digit1
.try_map(|s| -> Result<RawToken, std::num::ParseIntError> {
let num = str::parse::<u64>(s)?;
Expand All @@ -42,7 +42,7 @@ fn number(input: &str) -> IResult<&str, RawToken> {
.parse_next(input)
}

fn qualifier(input: &str) -> IResult<&str, RawToken> {
fn qualifier<'a>(input: &mut &'a str) -> PResult<RawToken<'a>> {
take_while(
1..,
|c: char| matches!(c, 'a'..='z' | 'A'..='Z' | '+' | '_'),
Expand All @@ -51,19 +51,19 @@ fn qualifier(input: &str) -> IResult<&str, RawToken> {
.parse_next(input)
}

fn dot_separator(input: &str) -> IResult<&str, RawToken> {
fn dot_separator<'a>(input: &mut &'a str) -> PResult<RawToken<'a>> {
'.'.map(|_| RawToken::DotChar).parse_next(input)
}

fn hyphen_separator(input: &str) -> IResult<&str, RawToken> {
fn hyphen_separator<'a>(input: &mut &'a str) -> PResult<RawToken<'a>> {
'-'.map(|_| RawToken::HyphenChar).parse_next(input)
}

fn raw_token(input: &str) -> IResult<&str, RawToken> {
fn raw_token<'a>(input: &mut &'a str) -> PResult<RawToken<'a>> {
alt((number, dot_separator, hyphen_separator, qualifier)).parse_next(input)
}

fn raw_tokens(input: &str) -> IResult<&str, Vec<RawToken>> {
fn raw_tokens<'a>(input: &mut &'a str) -> PResult<Vec<RawToken<'a>>> {
repeat(1.., raw_token).parse_next(input)
}

Expand Down Expand Up @@ -166,10 +166,10 @@ fn parse_raw_tokens(raw_tokens: Vec<RawToken>) -> Vec<Token> {
tokens
}

fn version_tokens(input: &str) -> IResult<&str, Version> {
fn version_tokens(input: &mut &'_ str) -> PResult<Version> {
raw_tokens
.map(parse_raw_tokens)
.map(Version::from_tokens)
.map(|tokens| Version { tokens })
.parse_next(input)
}

Expand Down Expand Up @@ -231,19 +231,11 @@ struct Version {
tokens: Vec<Token>,
}

impl Version {
fn from_tokens(tokens: Vec<Token>) -> Version {
Version { tokens }
}
impl std::str::FromStr for Version {
type Err = String;

fn parse(input: &str) -> Option<Version> {
match (version_tokens, eof)
.map(|(version, _)| version)
.parse_next(input)
{
Ok((_, version)) => Some(version),
_ => None,
}
fn from_str(s: &str) -> Result<Self, Self::Err> {
version_tokens.parse(s).map_err(|e| e.to_string())
}
}

Expand Down
59 changes: 30 additions & 29 deletions src/maven/version_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use insta::*;
use itertools::Itertools;
use rstest::rstest;
use serde::ser::{Serialize, SerializeStruct, Serializer};
use std::str::FromStr;

/// @see https://github.com/apache/maven/blob/master/maven-artifact/src/test/java/org/apache/maven/artifact/versioning/ComparableVersionTest.java

Expand All @@ -15,7 +16,7 @@ use serde::ser::{Serialize, SerializeStruct, Serializer};
#[case("000123", 123)]
#[case("000123000", 123000)]
fn parse_number(#[case] input: &str, #[case] expected: u64) {
let (_, res) = number(input).unwrap();
let (_, res) = number.parse_peek(input).unwrap();
if let RawToken::Num(res) = res {
assert_eq!(res, expected);
} else {
Expand All @@ -31,7 +32,7 @@ fn parse_number(#[case] input: &str, #[case] expected: u64) {
#[case("foo.bar", "foo")]
#[case("foo-bar", "foo")]
fn parse_qualifier(#[case] input: &str, #[case] expected: &str) {
let (_, res) = qualifier(input).unwrap();
let (_, res) = qualifier.parse_peek(input).unwrap();
if let RawToken::Qual(res) = res {
assert_eq!(res, expected);
} else {
Expand Down Expand Up @@ -115,7 +116,7 @@ where
#[test]
fn tokenization() {
let get_tokens = |input: &str| -> Vec<Token> {
let (_, output) = version_tokens(input).unwrap();
let output = version_tokens.parse(input).unwrap();
output.tokens
};

Expand All @@ -138,13 +139,13 @@ fn tokenization() {
#[case("1.0.0-foo.0.0", "1-foo")]
#[case("1.0.0-0.0.0", "1")]
fn equivalent_tokenization(#[case] input: &str, #[case] expected: &str) {
assert_eq!(version_tokens(input), version_tokens(expected));
assert_eq!(version_tokens.parse(input), version_tokens.parse(expected));
}

#[test]
fn version_constructor() {
assert_eq!(
Version::parse("1.2.3").unwrap(),
Version::from_str("1.2.3").unwrap(),
Version {
tokens: vec![
Token {
Expand All @@ -163,7 +164,7 @@ fn version_constructor() {
}
);

assert!(Version::parse("1.2.3=#!").is_none());
assert!(Version::from_str("1.2.3=#!").is_err());
}

#[rstest]
Expand Down Expand Up @@ -217,8 +218,8 @@ fn version_constructor() {
#[case("1.0.0.x", "1-x")]
#[case("1.x", "1.0.0-x")]
fn equality(#[case] left: &str, #[case] right: &str) {
let left = Version::parse(left).unwrap();
let right = Version::parse(right).unwrap();
let left = Version::from_str(left).unwrap();
let right = Version::from_str(right).unwrap();
assert_eq!(left.partial_cmp(&right), Some(Ordering::Equal));
assert_eq!(right.partial_cmp(&left), Some(Ordering::Equal));
}
Expand Down Expand Up @@ -247,18 +248,18 @@ fn equality(#[case] left: &str, #[case] right: &str) {
#[case("2.0.1", "2.0.1-123")]
#[case("2.0.1-xyz", "2.0.1-123")]
fn comparison(#[case] left: &str, #[case] right: &str) {
let left = Version::parse(left).unwrap();
let right = Version::parse(right).unwrap();
let left = Version::from_str(left).unwrap();
let right = Version::from_str(right).unwrap();
assert_eq!(left.partial_cmp(&right), Some(Ordering::Less));
assert_eq!(right.partial_cmp(&left), Some(Ordering::Greater));
}

/// @see https://issues.apache.org/jira/browse/MNG-5568
#[test]
fn mng_5568() {
let a = Version::parse("6.1.0").unwrap();
let b = Version::parse("6.1.0rc3").unwrap();
let c = Version::parse("6.1H.5-beta").unwrap(); // this is the unusual version string, with 'H' in the middle
let a = Version::from_str("6.1.0").unwrap();
let b = Version::from_str("6.1.0rc3").unwrap();
let c = Version::from_str("6.1H.5-beta").unwrap(); // this is the unusual version string, with 'H' in the middle

assert_eq!(b.partial_cmp(&a), Some(Ordering::Less)); // classical
assert_eq!(b.partial_cmp(&c), Some(Ordering::Less)); // now b < c, but before MNG-5568, we had b > c
Expand All @@ -268,10 +269,10 @@ fn mng_5568() {
/// @see https://jira.apache.org/jira/browse/MNG-6572
#[test]
fn mng_6572() {
let a = Version::parse("20190126.230843").unwrap(); // resembles a SNAPSHOT
let b = Version::parse("1234567890.12345").unwrap(); // 10 digit number
let c = Version::parse("123456789012345.1H.5-beta").unwrap(); // 15 digit number
let d = Version::parse("12345678901234567890.1H.5-beta").unwrap(); // 20 digit number
let a = Version::from_str("20190126.230843").unwrap(); // resembles a SNAPSHOT
let b = Version::from_str("1234567890.12345").unwrap(); // 10 digit number
let c = Version::from_str("123456789012345.1H.5-beta").unwrap(); // 15 digit number
let d = Version::from_str("12345678901234567890.1H.5-beta").unwrap(); // 20 digit number

assert_eq!(a.partial_cmp(&b), Some(Ordering::Less));
assert_eq!(b.partial_cmp(&c), Some(Ordering::Less));
Expand Down Expand Up @@ -307,8 +308,8 @@ fn version_equal_with_leading_zeroes() {

for combination in versions.into_iter().combinations(2) {
let (left, right) = (combination[0], combination[1]);
let left = Version::parse(left).unwrap();
let right = Version::parse(right).unwrap();
let left = Version::from_str(left).unwrap();
let right = Version::from_str(right).unwrap();
assert_eq!(left.partial_cmp(&right), Some(Ordering::Equal));
assert_eq!(right.partial_cmp(&left), Some(Ordering::Equal));
}
Expand Down Expand Up @@ -340,8 +341,8 @@ fn test_version_zero_equal_with_leading_zeroes() {

for combination in versions.into_iter().combinations(2) {
let (left, right) = (combination[0], combination[1]);
let left = Version::parse(left).unwrap();
let right = Version::parse(right).unwrap();
let left = Version::from_str(left).unwrap();
let right = Version::from_str(right).unwrap();
assert_eq!(left.partial_cmp(&right), Some(Ordering::Equal));
assert_eq!(right.partial_cmp(&left), Some(Ordering::Equal));
}
Expand All @@ -350,9 +351,9 @@ fn test_version_zero_equal_with_leading_zeroes() {
/// @see https://issues.apache.org/jira/browse/MNG-6964
#[test]
fn test_mng_6964() {
let a = Version::parse("1-0.alpha").unwrap();
let b = Version::parse("1-0.beta").unwrap();
let c = Version::parse("1").unwrap();
let a = Version::from_str("1-0.alpha").unwrap();
let b = Version::from_str("1-0.beta").unwrap();
let c = Version::from_str("1").unwrap();

assert_eq!(a.partial_cmp(&c), Some(Ordering::Less)); // Now a < c, but before MNG-6964 they were equal
assert_eq!(b.partial_cmp(&c), Some(Ordering::Less)); // Now b < c, but before MNG-6964 they were equal
Expand All @@ -376,14 +377,14 @@ fn test_mng_7644() {

for qual in quals {
// 1.0.0.X1 < 1.0.0-X2 for any string x
let a = Version::parse(&format!("1.0.0.{}1", qual)).unwrap();
let b = Version::parse(&format!("1.0.0-{}2", qual)).unwrap();
let a = Version::from_str(&format!("1.0.0.{}1", qual)).unwrap();
let b = Version::from_str(&format!("1.0.0-{}2", qual)).unwrap();
assert_eq!(a.partial_cmp(&b), Some(Ordering::Less));

// 2.0.X == 2-X == 2.0.0.X for any string x
let c = Version::parse(&format!("2-{}", qual)).unwrap();
let d = Version::parse(&format!("2.0.{}", qual)).unwrap();
let e = Version::parse(&format!("2.0.0.{}", qual)).unwrap();
let c = Version::from_str(&format!("2-{}", qual)).unwrap();
let d = Version::from_str(&format!("2.0.{}", qual)).unwrap();
let e = Version::from_str(&format!("2.0.0.{}", qual)).unwrap();
assert_eq!(c.partial_cmp(&d), Some(Ordering::Equal)); // previously ordered, now equals
assert_eq!(c.partial_cmp(&e), Some(Ordering::Equal)); // previously ordered, now equals
assert_eq!(d.partial_cmp(&e), Some(Ordering::Equal)); // previously ordered, now equals
Expand Down

0 comments on commit 88fccad

Please sign in to comment.