diff --git a/src/atom/mod.rs b/src/atom/mod.rs index 6b2b51f..cee9c29 100644 --- a/src/atom/mod.rs +++ b/src/atom/mod.rs @@ -185,6 +185,28 @@ impl Atom { } } +impl VersionNumber { + #[must_use] + pub fn cmp_as_ints(&self, other: &Self) -> Ordering { + let a = self.get().trim_start_matches('0'); + let b = other.get().trim_start_matches('0'); + + a.len().cmp(&b.len()).then_with(|| a.cmp(b)) + } + + #[must_use] + pub fn cmp_as_str(&self, other: &Self) -> Ordering { + if self.get().starts_with('0') || other.get().starts_with('0') { + let a = self.get().trim_end_matches('0'); + let b = other.get().trim_end_matches('0'); + + a.cmp(b) + } else { + self.cmp_as_ints(other) + } + } +} + impl PartialEq for VersionSuffix { fn eq(&self, other: &Self) -> bool { self.kind == other.kind @@ -212,11 +234,7 @@ impl Ord for VersionSuffix { Ordering::Less => Ordering::Less, Ordering::Greater => Ordering::Greater, Ordering::Equal => match (&self.number, &other.number) { - (Some(a), Some(b)) => { - a.0.parse::() - .unwrap() - .cmp(&b.0.parse::().unwrap()) - } + (Some(a), Some(b)) => a.cmp_as_ints(b), (Some(a), None) if a.get().chars().all(|c| c == '0') => Ordering::Equal, (None, Some(b)) if b.get().chars().all(|c| c == '0') => Ordering::Equal, (Some(_), None) => Ordering::Greater, @@ -276,26 +294,21 @@ impl Ord for VersionSuffixes { impl PartialEq for VersionNumbers { fn eq(&self, other: &Self) -> bool { - self.get().first().unwrap().get().parse::().unwrap() - == other.get().first().unwrap().get().parse().unwrap() + self.get() + .first() + .unwrap() + .cmp_as_ints(other.get().first().unwrap()) + == Ordering::Equal && { let mut a = self.get().iter().skip(1); let mut b = other.get().iter().skip(1); loop { match (a.next(), b.next()) { - (Some(a), Some(b)) if a.get().starts_with('0') => { - let a = a.get().trim_end_matches('0'); - let b = b.get().trim_end_matches('0'); - - if a != b { - break false; - } - } (Some(a), Some(b)) => { - if a.get().parse::().unwrap() != b.get().parse::().unwrap() { - break false; - } + let Ordering::Equal = a.cmp_as_str(b) else { + return false; + }; } (Some(a), None) if a.get().chars().all(|c| c == '0') => (), (None, Some(b)) if b.get().chars().all(|c| c == '0') => (), @@ -321,10 +334,7 @@ impl Ord for VersionNumbers { .get() .first() .unwrap() - .get() - .parse::() - .unwrap() - .cmp(&other.get().first().unwrap().get().parse::().unwrap()) + .cmp_as_ints(other.get().first().unwrap()) { Ordering::Less => Ordering::Less, Ordering::Greater => Ordering::Greater, @@ -334,24 +344,7 @@ impl Ord for VersionNumbers { loop { match (a.next(), b.next()) { - (Some(a), Some(b)) - if a.get().starts_with('0') || b.get().starts_with('0') => - { - let a = a.get().trim_end_matches('0'); - let b = b.get().trim_end_matches('0'); - - match a.cmp(b) { - Ordering::Less => break Ordering::Less, - Ordering::Greater => break Ordering::Greater, - Ordering::Equal => (), - } - } - (Some(a), Some(b)) => match a - .get() - .parse::() - .unwrap() - .cmp(&b.get().parse::().unwrap()) - { + (Some(a), Some(b)) => match a.cmp_as_str(b) { Ordering::Less => break Ordering::Less, Ordering::Greater => break Ordering::Greater, Ordering::Equal => (), @@ -373,18 +366,14 @@ impl PartialEq for Version { && self.suffixes == other.suffixes && self.letter == other.letter && match (&self.rev, &other.rev) { - (Some(a), Some(b)) => { - a.get().parse::().unwrap() == b.get().parse::().unwrap() - } + (Some(a), Some(b)) => matches!(a.cmp_as_ints(b), Ordering::Equal), (Some(a), None) if a.get().chars().all(|c| c == '0') => true, (None, Some(b)) if b.get().chars().all(|c| c == '0') => true, (Some(_), None) | (None, Some(_)) => false, (None, None) => true, } && match (&self.build_id, &other.build_id) { - (Some(a), Some(b)) => { - a.get().parse::().unwrap() == b.get().parse::().unwrap() - } + (Some(a), Some(b)) => matches!(a.cmp_as_ints(b), Ordering::Equal), (Some(_), None) | (None, Some(_)) => false, (None, None) => true, } @@ -424,12 +413,7 @@ impl Ord for Version { } match (&self.rev, &other.rev) { - (Some(a), Some(b)) => match a - .get() - .parse::() - .unwrap() - .cmp(&b.get().parse().unwrap()) - { + (Some(a), Some(b)) => match a.cmp_as_ints(b) { Ordering::Less => return Ordering::Less, Ordering::Greater => return Ordering::Greater, Ordering::Equal => (), @@ -442,11 +426,7 @@ impl Ord for Version { } match (&self.build_id, &other.build_id) { - (Some(a), Some(b)) => a - .get() - .parse::() - .unwrap() - .cmp(&b.get().parse::().unwrap()), + (Some(a), Some(b)) => a.cmp_as_ints(b), (Some(_), None) => Ordering::Greater, (None, Some(_)) => Ordering::Less, (None, None) => Ordering::Equal,