@@ -1600,20 +1600,102 @@ impl EnvironmentPreference {
1600
1600
}
1601
1601
}
1602
1602
1603
- #[ derive( Debug , Clone , Copy ) ]
1603
+ #[ derive( Debug , Clone , Default , Copy , PartialEq , Eq ) ]
1604
1604
pub ( crate ) struct ExecutableName {
1605
- name : & ' static str ,
1605
+ implementation : Option < ImplementationName > ,
1606
1606
major : Option < u8 > ,
1607
1607
minor : Option < u8 > ,
1608
1608
patch : Option < u8 > ,
1609
1609
prerelease : Option < Prerelease > ,
1610
1610
variant : PythonVariant ,
1611
1611
}
1612
1612
1613
+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
1614
+ struct ExecutableNameComparator < ' a > {
1615
+ name : ExecutableName ,
1616
+ request : & ' a VersionRequest ,
1617
+ implementation : Option < & ' a ImplementationName > ,
1618
+ }
1619
+
1620
+ impl Ord for ExecutableNameComparator < ' _ > {
1621
+ /// Note the comparison returns a reverse priority ordering.
1622
+ ///
1623
+ /// Higher priority items are "Greater" than lower priority items.
1624
+ fn cmp ( & self , other : & Self ) -> std:: cmp:: Ordering {
1625
+ // Prefer the default name over a specific implementation, unless an implementation was
1626
+ // requested
1627
+ let name_ordering = if self . implementation . is_some ( ) {
1628
+ std:: cmp:: Ordering :: Greater
1629
+ } else {
1630
+ std:: cmp:: Ordering :: Less
1631
+ } ;
1632
+ if self . name . implementation . is_none ( ) && other. name . implementation . is_some ( ) {
1633
+ return name_ordering. reverse ( ) ;
1634
+ }
1635
+ if self . name . implementation . is_some ( ) && other. name . implementation . is_none ( ) {
1636
+ return name_ordering;
1637
+ }
1638
+ // Otherwise, use the names in supported order
1639
+ let ordering = self . name . implementation . cmp ( & other. name . implementation ) ;
1640
+ if ordering != std:: cmp:: Ordering :: Equal {
1641
+ return ordering;
1642
+ }
1643
+ let ordering = self . name . major . cmp ( & other. name . major ) ;
1644
+ let is_default_request =
1645
+ matches ! ( self . request, VersionRequest :: Any | VersionRequest :: Default ) ;
1646
+ if ordering != std:: cmp:: Ordering :: Equal {
1647
+ return if is_default_request {
1648
+ ordering. reverse ( )
1649
+ } else {
1650
+ ordering
1651
+ } ;
1652
+ }
1653
+ let ordering = self . name . minor . cmp ( & other. name . minor ) ;
1654
+ if ordering != std:: cmp:: Ordering :: Equal {
1655
+ return if is_default_request {
1656
+ ordering. reverse ( )
1657
+ } else {
1658
+ ordering
1659
+ } ;
1660
+ }
1661
+ let ordering = self . name . patch . cmp ( & other. name . patch ) ;
1662
+ if ordering != std:: cmp:: Ordering :: Equal {
1663
+ return if is_default_request {
1664
+ ordering. reverse ( )
1665
+ } else {
1666
+ ordering
1667
+ } ;
1668
+ }
1669
+ let ordering = self . name . prerelease . cmp ( & other. name . prerelease ) ;
1670
+ if ordering != std:: cmp:: Ordering :: Equal {
1671
+ return if is_default_request {
1672
+ ordering. reverse ( )
1673
+ } else {
1674
+ ordering
1675
+ } ;
1676
+ }
1677
+ let ordering = self . name . variant . cmp ( & other. name . variant ) ;
1678
+ if ordering != std:: cmp:: Ordering :: Equal {
1679
+ return if is_default_request {
1680
+ ordering. reverse ( )
1681
+ } else {
1682
+ ordering
1683
+ } ;
1684
+ }
1685
+ ordering
1686
+ }
1687
+ }
1688
+
1689
+ impl PartialOrd for ExecutableNameComparator < ' _ > {
1690
+ fn partial_cmp ( & self , other : & Self ) -> Option < std:: cmp:: Ordering > {
1691
+ Some ( self . cmp ( other) )
1692
+ }
1693
+ }
1694
+
1613
1695
impl ExecutableName {
1614
1696
#[ must_use]
1615
- fn with_name ( mut self , name : & ' static str ) -> Self {
1616
- self . name = name ;
1697
+ fn with_implementation ( mut self , implementation : ImplementationName ) -> Self {
1698
+ self . implementation = Some ( implementation ) ;
1617
1699
self
1618
1700
}
1619
1701
@@ -1646,24 +1728,27 @@ impl ExecutableName {
1646
1728
self . variant = variant;
1647
1729
self
1648
1730
}
1649
- }
1650
1731
1651
- impl Default for ExecutableName {
1652
- fn default ( ) -> Self {
1653
- Self {
1654
- name : "python" ,
1655
- major : None ,
1656
- minor : None ,
1657
- patch : None ,
1658
- prerelease : None ,
1659
- variant : PythonVariant :: Default ,
1732
+ fn into_comparator < ' a > (
1733
+ self ,
1734
+ request : & ' a VersionRequest ,
1735
+ implementation : Option < & ' a ImplementationName > ,
1736
+ ) -> ExecutableNameComparator < ' a > {
1737
+ ExecutableNameComparator {
1738
+ name : self ,
1739
+ request ,
1740
+ implementation ,
1660
1741
}
1661
1742
}
1662
1743
}
1663
1744
1664
1745
impl std:: fmt:: Display for ExecutableName {
1665
1746
fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
1666
- write ! ( f, "{}" , self . name) ?;
1747
+ if let Some ( implementation) = self . implementation {
1748
+ write ! ( f, "{implementation}" ) ?;
1749
+ } else {
1750
+ f. write_str ( "python" ) ?;
1751
+ }
1667
1752
if let Some ( major) = self . major {
1668
1753
write ! ( f, "{major}" ) ?;
1669
1754
if let Some ( minor) = self . minor {
@@ -1741,15 +1826,15 @@ impl VersionRequest {
1741
1826
// Add all the implementation-specific names
1742
1827
if let Some ( implementation) = implementation {
1743
1828
for i in 0 ..names. len ( ) {
1744
- let name = names[ i] . with_name ( implementation. into ( ) ) ;
1829
+ let name = names[ i] . with_implementation ( * implementation) ;
1745
1830
names. push ( name) ;
1746
1831
}
1747
1832
} else {
1748
1833
// When looking for all implementations, include all possible names
1749
1834
if matches ! ( self , Self :: Any ) {
1750
1835
for i in 0 ..names. len ( ) {
1751
- for implementation in ImplementationName :: long_names ( ) {
1752
- let name = names[ i] . with_name ( implementation) ;
1836
+ for implementation in ImplementationName :: iter_all ( ) {
1837
+ let name = names[ i] . with_implementation ( implementation) ;
1753
1838
names. push ( name) ;
1754
1839
}
1755
1840
}
@@ -1764,6 +1849,9 @@ impl VersionRequest {
1764
1849
}
1765
1850
}
1766
1851
1852
+ names. sort_unstable_by_key ( |name| name. into_comparator ( self , implementation) ) ;
1853
+ names. reverse ( ) ;
1854
+
1767
1855
names
1768
1856
}
1769
1857
0 commit comments