Clearer registry Python sort (#7178)

Change the registry Python sorting implementation to be easier to
follow, making it clearer what it does and that it is a total order. No
functional changes.
This commit is contained in:
konsti 2024-09-07 21:57:01 +02:00 committed by GitHub
parent 8341d810b2
commit aca01f80ef
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,4 +1,5 @@
use crate::PythonVersion; use crate::PythonVersion;
use std::cmp::Ordering;
use std::path::PathBuf; use std::path::PathBuf;
use std::str::FromStr; use std::str::FromStr;
use tracing::debug; use tracing::debug;
@ -52,16 +53,17 @@ pub(crate) fn registry_pythons() -> Result<Vec<WindowsPython>, windows_result::E
// The registry has no natural ordering, so we're processing the latest version first. // The registry has no natural ordering, so we're processing the latest version first.
registry_pythons.sort_by(|a, b| { registry_pythons.sort_by(|a, b| {
// Highest version first (reverse), but entries without version at the bottom (regular match (&a.version, &b.version) {
// order). // Place entries with a version before those without a version.
if let (Some(version_a), Some(version_b)) = (&a.version, &b.version) { (Some(_), None) => Ordering::Greater,
version_a.cmp(version_b).reverse().then(a.path.cmp(&b.path)) (None, Some(_)) => Ordering::Less,
} else { // We want the highest version on top, which is the inverse from the regular order. The
a.version // path is an arbitrary but stable tie-breaker.
.as_ref() (Some(version_a), Some(version_b)) => {
.map(|version| &***version) version_a.cmp(version_b).reverse().then(a.path.cmp(&b.path))
.cmp(&b.version.as_ref().map(|version| &***version)) }
.then(a.path.cmp(&b.path)) // Sort the entries without a version arbitrarily, but stable (by path).
(None, None) => a.path.cmp(&b.path),
} }
}); });