summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Turner <jturner.usa@gmail.com>2025-11-21 04:33:55 +0000
committerJohn Turner <jturner.usa@gmail.com>2025-11-21 04:33:55 +0000
commitfb69d82e6f1dce4677114e717a5954bb9ab5c0e4 (patch)
tree821f9aab0609c7242e333e1ac0819aca1b3ceef4
parentbf56ed1c61905b3abdba70aea84622619cffd8da (diff)
downloadgentoo-utils-fb69d82e6f1dce4677114e717a5954bb9ab5c0e4.tar.gz
build-id must not start with zero
-rw-r--r--src/atom/mod.rs31
-rw-r--r--src/atom/parsers.rs24
2 files changed, 47 insertions, 8 deletions
diff --git a/src/atom/mod.rs b/src/atom/mod.rs
index 8cffa06..82cef15 100644
--- a/src/atom/mod.rs
+++ b/src/atom/mod.rs
@@ -58,13 +58,16 @@ pub struct VersionSuffix {
#[derive(Debug, Clone, Get)]
pub struct VersionSuffixes(#[get(method = "get", kind = "deref")] Vec<VersionSuffix>);
+#[derive(Debug, Clone, Get, PartialEq, Eq)]
+pub struct BuildId(#[get(method = "get", kind = "deref")] String);
+
#[derive(Clone, Debug, Get)]
pub struct Version {
numbers: VersionNumbers,
letter: Option<char>,
suffixes: VersionSuffixes,
rev: Option<VersionNumber>,
- build_id: Option<VersionNumber>,
+ build_id: Option<BuildId>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
@@ -207,6 +210,22 @@ impl VersionNumber {
}
}
+impl PartialOrd for BuildId {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ Some(self.cmp(other))
+ }
+}
+
+impl Ord for BuildId {
+ fn cmp(&self, other: &Self) -> Ordering {
+ // build-id may not start with a zero so we dont need to strip them
+ self.get()
+ .len()
+ .cmp(&other.get().len())
+ .then_with(|| self.get().cmp(other.get()))
+ }
+}
+
impl PartialEq for VersionSuffix {
fn eq(&self, other: &Self) -> bool {
self.kind == other.kind
@@ -373,7 +392,7 @@ impl PartialEq for Version {
(None, None) => true,
}
&& match (&self.build_id, &other.build_id) {
- (Some(a), Some(b)) => matches!(a.cmp_as_ints(b), Ordering::Equal),
+ (Some(a), Some(b)) => a == b,
(Some(_), None) | (None, Some(_)) => false,
(None, None) => true,
}
@@ -426,7 +445,7 @@ impl Ord for Version {
}
match (&self.build_id, &other.build_id) {
- (Some(a), Some(b)) => a.cmp_as_ints(b),
+ (Some(a), Some(b)) => a.cmp(b),
(Some(_), None) => Ordering::Greater,
(None, Some(_)) => Ordering::Less,
(None, None) => Ordering::Equal,
@@ -484,6 +503,12 @@ impl fmt::Display for VersionNumber {
}
}
+impl fmt::Display for BuildId {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "{}", self.get())
+ }
+}
+
impl fmt::Display for VersionSuffixKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
diff --git a/src/atom/parsers.rs b/src/atom/parsers.rs
index 301409c..df0890f 100644
--- a/src/atom/parsers.rs
+++ b/src/atom/parsers.rs
@@ -1,15 +1,15 @@
use core::option::Option::None;
use mon::{
- Parser, ParserIter, ascii_alphanumeric, ascii_numeric1, eof, r#if, input::InputIter, one_of,
- tag,
+ Parser, ParserIter, ascii_alphanumeric, ascii_numeric, ascii_numeric1, eof, r#if,
+ input::InputIter, one_of, tag,
};
use crate::{
Parseable,
atom::{
- Atom, Blocker, Category, Cp, Cpv, Name, Repo, Slot, SlotName, SlotOperator, UseDep,
- UseDepCondition, UseDepNegate, UseDepSign, Version, VersionNumber, VersionNumbers,
+ Atom, Blocker, BuildId, Category, Cp, Cpv, Name, Repo, Slot, SlotName, SlotOperator,
+ UseDep, UseDepCondition, UseDepNegate, UseDepSign, Version, VersionNumber, VersionNumbers,
VersionOperator, VersionSuffix, VersionSuffixKind, VersionSuffixes, Wildcard,
},
useflag::UseFlag,
@@ -47,6 +47,20 @@ impl<'a> Parseable<'a, &'a str> for VersionNumber {
}
}
+impl<'a> Parseable<'a, &'a str> for BuildId {
+ type Parser = impl Parser<&'a str, Output = Self>;
+
+ fn parser() -> Self::Parser {
+ let start = ascii_numeric().and_not(tag("0"));
+ let rest = ascii_numeric().repeated().many();
+
+ start
+ .and(rest)
+ .recognize()
+ .map(|output: &str| BuildId(output.to_string()))
+ }
+}
+
impl<'a> Parseable<'a, &'a str> for VersionSuffixKind {
type Parser = impl Parser<&'a str, Output = Self>;
@@ -97,7 +111,7 @@ impl<'a> Parseable<'a, &'a str> for Version {
fn parser() -> Self::Parser {
let rev = VersionNumber::parser().preceded_by(tag("-r"));
- let build_id = VersionNumber::parser().preceded_by(tag("-"));
+ let build_id = BuildId::parser().preceded_by(tag("-"));
VersionNumbers::parser()
.and(r#if(|c: &char| c.is_ascii_alphabetic() && c.is_ascii_lowercase()).opt())