impl Cpv type

This commit is contained in:
John Turner
2025-11-13 18:03:34 +00:00
parent f4a45717d2
commit 1882ce3137
2 changed files with 65 additions and 1 deletions

View File

@@ -108,6 +108,13 @@ pub struct UseDep {
condition: Option<UseDepCondition>,
}
#[derive(Clone, Debug, PartialEq, Eq, Get)]
pub struct Cpv {
category: Category,
name: Name,
version: Version,
}
#[derive(Clone, Debug, Get, PartialEq, Eq)]
pub struct Atom {
blocker: Option<Blocker>,
@@ -361,6 +368,16 @@ impl Ord for Version {
}
}
impl PartialOrd for Cpv {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
if self.category == other.category && self.name == other.name {
Some(self.version.cmp(&other.version))
} else {
None
}
}
}
impl fmt::Display for Blocker {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
@@ -541,6 +558,12 @@ impl fmt::Display for UseDep {
}
}
impl fmt::Display for Cpv {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}/{}-{}", &self.category, &self.name, &self.version)
}
}
impl fmt::Display for Atom {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(blocker) = self.blocker.as_ref() {
@@ -602,6 +625,14 @@ mod test {
};
}
macro_rules! assert_partial_cmp_display {
($a:expr, $b:expr, $ordering:expr) => {
if $a.partial_cmp(&$b) != $ordering {
panic!("{} ~ {} != {:?}", $a, $b, $ordering)
}
};
}
#[test]
fn test_version_display() {
let s = "1.0.0_alpha1_beta1-r1";
@@ -670,4 +701,22 @@ mod test {
assert_cmp_display!(a, b, *ordering);
}
}
#[test]
fn test_cpv_eq() {
let cpvs = [
("foo/bar-1", "foo/bar-1", Some(Ordering::Equal)),
("foo/baz-1", "foo/bar-1", None),
];
for (a, b, ordering) in cpvs.iter().copied().map(|(a, b, ordering)| {
(
Cpv::parser().parse_finished(InputIter::new(a)).unwrap(),
Cpv::parser().parse_finished(InputIter::new(b)).unwrap(),
ordering,
)
}) {
assert_partial_cmp_display!(a, b, ordering);
}
}
}

View File

@@ -5,7 +5,7 @@ use mon::{Parser, ParserIter, r#if, numeric1, one_of, tag};
use crate::{
Parseable,
atom::{
Atom, Blocker, Category, Name, Slot, SlotName, SlotOperator, UseDep, UseDepCondition,
Atom, Blocker, Category, Cpv, Name, Slot, SlotName, SlotOperator, UseDep, UseDepCondition,
UseDepNegate, UseDepSign, Version, VersionNumber, VersionNumbers, VersionOperator,
VersionSuffix, VersionSuffixKind, VersionSuffixes,
},
@@ -334,6 +334,21 @@ impl<'a> Parseable<'a, &'a str> for Atom {
}
}
impl<'a> Parseable<'a, &'a str> for Cpv {
type Parser = impl Parser<&'a str, Output = Self>;
fn parser() -> Self::Parser {
Category::parser()
.and(Name::parser().preceded_by(tag("/")))
.and(Version::parser().preceded_by(tag("-")))
.map(|((category, name), version)| Cpv {
category,
name,
version,
})
}
}
#[cfg(test)]
mod test {