From dba0c12349b2f835180a8f28851dfc8d25288e4a Mon Sep 17 00:00:00 2001
From: Zanie <contact@zanie.dev>
Date: Fri, 1 Dec 2023 13:28:14 -0600
Subject: [PATCH] Initial divergences from upstream (#1)

---
 src/internal/core.rs             |  2 +-
 src/internal/incompatibility.rs  |  4 ++--
 src/internal/partial_solution.rs | 18 ++++++++++++++++++
 src/lib.rs                       |  1 +
 src/range.rs                     | 17 +++++++++++++----
 src/solver.rs                    |  4 ++--
 src/term.rs                      |  2 +-
 7 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/src/internal/core.rs b/src/internal/core.rs
index fa986f34..9ba724ee 100644
--- a/src/internal/core.rs
+++ b/src/internal/core.rs
@@ -25,7 +25,7 @@ pub struct State<P: Package, VS: VersionSet, Priority: Ord + Clone> {
     root_package: P,
     root_version: VS::V,
 
-    incompatibilities: Map<P, Vec<IncompId<P, VS>>>,
+    pub incompatibilities: Map<P, Vec<IncompId<P, VS>>>,
 
     /// Store the ids of incompatibilities that are already contradicted.
     /// For each one keep track of the decision level when it was found to be contradicted.
diff --git a/src/internal/incompatibility.rs b/src/internal/incompatibility.rs
index 2dc6fbde..48d63761 100644
--- a/src/internal/incompatibility.rs
+++ b/src/internal/incompatibility.rs
@@ -34,14 +34,14 @@ use crate::version_set::VersionSet;
 #[derive(Debug, Clone)]
 pub struct Incompatibility<P: Package, VS: VersionSet> {
     package_terms: SmallMap<P, Term<VS>>,
-    kind: Kind<P, VS>,
+    pub kind: Kind<P, VS>,
 }
 
 /// Type alias of unique identifiers for incompatibilities.
 pub type IncompId<P, VS> = Id<Incompatibility<P, VS>>;
 
 #[derive(Debug, Clone)]
-enum Kind<P: Package, VS: VersionSet> {
+pub enum Kind<P: Package, VS: VersionSet> {
     /// Initial incompatibility aiming at picking the root package for the first decision.
     NotRoot(P, VS::V),
     /// There are no versions in the given range for this package.
diff --git a/src/internal/partial_solution.rs b/src/internal/partial_solution.rs
index cf1d24db..d6745993 100644
--- a/src/internal/partial_solution.rs
+++ b/src/internal/partial_solution.rs
@@ -257,6 +257,24 @@ impl<P: Package, VS: VersionSet, Priority: Ord + Clone> PartialSolution<P, VS, P
         }
     }
 
+    pub fn prioritized_packages(&self) -> impl Iterator<Item = (&P, &VS)> {
+        let check_all = self.changed_this_decision_level
+            == self.current_decision_level.0.saturating_sub(1) as usize;
+        let current_decision_level = self.current_decision_level;
+        self.package_assignments
+            .get_range(self.changed_this_decision_level..)
+            .unwrap()
+            .iter()
+            .filter(move |(_, pa)| {
+                // We only actually need to update the package if its Been changed
+                // since the last time we called prioritize.
+                // Which means it's highest decision level is the current decision level,
+                // or if we backtracked in the mean time.
+                check_all || pa.highest_decision_level == current_decision_level
+            })
+            .filter_map(|(p, pa)| pa.assignments_intersection.potential_package_filter(p))
+    }
+
     pub fn pick_highest_priority_pkg(
         &mut self,
         prioritizer: impl Fn(&P, &VS) -> Priority,
diff --git a/src/lib.rs b/src/lib.rs
index 3389e250..76752e3a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -221,6 +221,7 @@
 //! do not exist in your cache.
 
 #![warn(missing_docs)]
+#![allow(clippy::all, unreachable_pub)]
 
 pub mod error;
 pub mod package;
diff --git a/src/range.rs b/src/range.rs
index 7df77099..f0f92e40 100644
--- a/src/range.rs
+++ b/src/range.rs
@@ -197,7 +197,7 @@ impl<V: Ord> Range<V> {
                 .segments
                 .last()
                 .expect("if there is a first element, there must be a last element");
-            (start.as_ref(), end.1.as_ref())
+            (bound_as_ref(start), bound_as_ref(&end.1))
         })
     }
 
@@ -315,6 +315,15 @@ fn within_bounds<V: PartialOrd>(v: &V, segment: &Interval<V>) -> Ordering {
     Ordering::Greater
 }
 
+/// Implementation of [`Bound::as_ref`] which is currently marked as unstable.
+fn bound_as_ref<V>(bound: &Bound<V>) -> Bound<&V> {
+    match bound {
+        Included(v) => Included(v),
+        Excluded(v) => Excluded(v),
+        Unbounded => Unbounded,
+    }
+}
+
 fn valid_segment<T: PartialOrd>(start: &Bound<T>, end: &Bound<T>) -> bool {
     match (start, end) {
         (Included(s), Included(e)) => s <= e,
@@ -536,7 +545,7 @@ impl<V: Display + Eq> Display for Range<V> {
         } else {
             for (idx, segment) in self.segments.iter().enumerate() {
                 if idx > 0 {
-                    write!(f, " | ")?;
+                    write!(f, ", ")?;
                 }
                 match segment {
                     (Unbounded, Unbounded) => write!(f, "*")?,
@@ -545,9 +554,9 @@ impl<V: Display + Eq> Display for Range<V> {
                     (Included(v), Unbounded) => write!(f, ">={v}")?,
                     (Included(v), Included(b)) => {
                         if v == b {
-                            write!(f, "{v}")?
+                            write!(f, "=={v}")?
                         } else {
-                            write!(f, ">={v}, <={b}")?
+                            write!(f, ">={v},<={b}")?
                         }
                     }
                     (Included(v), Excluded(b)) => write!(f, ">={v}, <{b}")?,
diff --git a/src/solver.rs b/src/solver.rs
index 9ac2edfe..dc944960 100644
--- a/src/solver.rs
+++ b/src/solver.rs
@@ -75,8 +75,8 @@ use std::convert::Infallible;
 use std::error::Error;
 
 use crate::error::PubGrubError;
-use crate::internal::core::State;
-use crate::internal::incompatibility::Incompatibility;
+pub use crate::internal::core::State;
+pub use crate::internal::incompatibility::{Incompatibility, Kind};
 use crate::package::Package;
 use crate::type_aliases::{DependencyConstraints, Map, SelectedDependencies};
 use crate::version_set::VersionSet;
diff --git a/src/term.rs b/src/term.rs
index 2974da62..0043a13e 100644
--- a/src/term.rs
+++ b/src/term.rs
@@ -64,7 +64,7 @@ impl<VS: VersionSet> Term<VS> {
 
     /// Unwrap the set contained in a positive term.
     /// Will panic if used on a negative set.
-    pub(crate) fn unwrap_positive(&self) -> &VS {
+    pub fn unwrap_positive(&self) -> &VS {
         match self {
             Self::Positive(set) => set,
             _ => panic!("Negative term cannot unwrap positive set"),