impl version comparison algorithm

This commit is contained in:
2025-11-13 18:00:15 +00:00
parent 3b7a662598
commit f4a45717d2
2 changed files with 346 additions and 13 deletions

View File

@@ -6,8 +6,8 @@ use crate::{
Parseable,
atom::{
Atom, Blocker, Category, Name, Slot, SlotName, SlotOperator, UseDep, UseDepCondition,
UseDepNegate, UseDepSign, Version, VersionNumber, VersionOperator, VersionSuffix,
VersionSuffixKind,
UseDepNegate, UseDepSign, Version, VersionNumber, VersionNumbers, VersionOperator,
VersionSuffix, VersionSuffixKind, VersionSuffixes,
},
useflag::UseFlag,
};
@@ -67,22 +67,45 @@ impl<'a> Parseable<'a, &'a str> for VersionSuffix {
}
}
impl<'a> Parseable<'a, &'a str> for VersionNumbers {
type Parser = impl Parser<&'a str, Output = Self>;
fn parser() -> Self::Parser {
VersionNumber::parser()
.followed_by(tag("*").opt())
.recognize()
.map(|output: &str| VersionNumber(output.to_string()))
.separated_by(tag("."))
.at_least(1)
.map(|numbers| VersionNumbers(numbers))
}
}
impl<'a> Parseable<'a, &'a str> for VersionSuffixes {
type Parser = impl Parser<&'a str, Output = Self>;
fn parser() -> Self::Parser {
VersionSuffix::parser()
.separated_by(tag("_"))
.many()
.map(|suffixes| VersionSuffixes(suffixes))
}
}
impl<'a> Parseable<'a, &'a str> for Version {
type Parser = impl Parser<&'a str, Output = Self>;
fn parser() -> Self::Parser {
let numbers = VersionNumber::parser().separated_by(tag(".")).at_least(1);
let suffixes = VersionSuffix::parser().separated_by(tag("_")).many();
let rev = VersionNumber::parser().preceded_by(tag("-r"));
numbers
VersionNumbers::parser()
.and(r#if(|c: &char| c.is_ascii_alphabetic() && c.is_ascii_lowercase()).opt())
.and(suffixes.preceded_by(tag("_")).opt())
.and(VersionSuffixes::parser().preceded_by(tag("_")).opt())
.and(rev.opt())
.map(|(((numbers, letter), suffixes), rev)| Version {
numbers,
letter,
suffixes: suffixes.unwrap_or(Vec::new()),
suffixes: suffixes.unwrap_or(VersionSuffixes(Vec::new())),
rev,
})
}
@@ -298,6 +321,7 @@ impl<'a> Parseable<'a, &'a str> for Atom {
Some((_, version))
if !version
.numbers()
.get()
.iter()
.any(|number| number.get().contains("*")) =>
{