diff --git a/src/internal/arena.rs b/src/internal/arena.rs index 6edb85df..826de1a4 100644 --- a/src/internal/arena.rs +++ b/src/internal/arena.rs @@ -10,7 +10,7 @@ use std::ops::{Index, Range}; /// that we actually don't need since it is phantom. /// /// -pub(crate) struct Id { +pub struct Id { raw: u32, _ty: PhantomData T>, } @@ -71,7 +71,7 @@ impl Id { /// to have references between those items. /// They are all dropped at once when the arena is dropped. #[derive(Clone, PartialEq, Eq)] -pub(crate) struct Arena { +pub struct Arena { data: Vec, } diff --git a/src/internal/core.rs b/src/internal/core.rs index 0e30d15c..ac6d7757 100644 --- a/src/internal/core.rs +++ b/src/internal/core.rs @@ -14,12 +14,13 @@ use crate::{DependencyProvider, DerivationTree, Map, NoSolutionError, VersionSet /// Current state of the PubGrub algorithm. #[derive(Clone)] -pub(crate) struct State { +pub struct State { root_package: DP::P, root_version: DP::V, + /// All incompatibilities indexed by package. #[allow(clippy::type_complexity)] - incompatibilities: Map>>, + pub incompatibilities: Map>>, /// 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. @@ -32,11 +33,10 @@ pub(crate) struct State { merged_dependencies: Map<(DP::P, DP::P), SmallVec>>, /// Partial solution. - /// TODO: remove pub. - pub(crate) partial_solution: PartialSolution, + pub partial_solution: PartialSolution, /// The store is the reference storage for all incompatibilities. - pub(crate) incompatibility_store: Arena>, + pub incompatibility_store: Arena>, /// This is a stack of work to be done in `unit_propagation`. /// It can definitely be a local variable to that method, but @@ -46,7 +46,7 @@ pub(crate) struct State { impl State { /// Initialization of PubGrub state. - pub(crate) fn init(root_package: DP::P, root_version: DP::V) -> Self { + pub fn init(root_package: DP::P, root_version: DP::V) -> Self { let mut incompatibility_store = Arena::new(); let not_root_id = incompatibility_store.alloc(Incompatibility::not_root( root_package.clone(), @@ -67,7 +67,7 @@ impl State { } /// Add an incompatibility to the state. - pub(crate) fn add_incompatibility(&mut self, incompat: Incompatibility) { + pub fn add_incompatibility(&mut self, incompat: Incompatibility) { let id = self.incompatibility_store.alloc(incompat); self.merge_incompatibility(id); } @@ -98,7 +98,7 @@ impl State { /// Unit propagation is the core mechanism of the solving algorithm. /// CF - pub(crate) fn unit_propagation(&mut self, package: DP::P) -> Result<(), NoSolutionError> { + pub fn unit_propagation(&mut self, package: DP::P) -> Result<(), NoSolutionError> { self.unit_propagation_buffer.clear(); self.unit_propagation_buffer.push(package); while let Some(current_package) = self.unit_propagation_buffer.pop() { diff --git a/src/internal/incompatibility.rs b/src/internal/incompatibility.rs index 33b59cfe..082a0156 100644 --- a/src/internal/incompatibility.rs +++ b/src/internal/incompatibility.rs @@ -28,9 +28,10 @@ use crate::{ /// during conflict resolution. More about all this in /// [PubGrub documentation](https://github.com/dart-lang/pub/blob/master/doc/solver.md#incompatibility). #[derive(Debug, Clone)] -pub(crate) struct Incompatibility { +pub struct Incompatibility { package_terms: SmallMap>, - kind: Kind, + /// The reason for the incompatibility. + pub kind: Kind, } /// Type alias of unique identifiers for incompatibilities. @@ -42,8 +43,9 @@ pub(crate) type IncompDpId = IncompId< ::M, >; +/// The reason for the incompatibility. #[derive(Debug, Clone)] -enum Kind { +pub enum Kind { /// Initial incompatibility aiming at picking the root package for the first decision. /// /// This incompatibility drives the resolution, it requires that we pick the (virtual) root @@ -104,7 +106,7 @@ impl Incompatibilit } /// Create an incompatibility to remember that a given set does not contain any version. - pub(crate) fn no_versions(package: P, term: Term) -> Self { + pub fn no_versions(package: P, term: Term) -> Self { let set = match &term { Term::Positive(r) => r.clone(), Term::Negative(_) => panic!("No version should have a positive term"), @@ -117,7 +119,7 @@ impl Incompatibilit /// Create an incompatibility for a reason outside pubgrub. #[allow(dead_code)] // Used by uv - pub(crate) fn custom_term(package: P, term: Term, metadata: M) -> Self { + pub fn custom_term(package: P, term: Term, metadata: M) -> Self { let set = match &term { Term::Positive(r) => r.clone(), Term::Negative(_) => panic!("No version should have a positive term"), @@ -129,7 +131,7 @@ impl Incompatibilit } /// Create an incompatibility for a reason outside pubgrub. - pub(crate) fn custom_version(package: P, version: VS::V, metadata: M) -> Self { + pub fn custom_version(package: P, version: VS::V, metadata: M) -> Self { let set = VS::singleton(version); let term = Term::Positive(set.clone()); Self { @@ -139,7 +141,7 @@ impl Incompatibilit } /// Build an incompatibility from a given dependency. - pub(crate) fn from_dependency(package: P, versions: VS, dep: (P, VS)) -> Self { + pub fn from_dependency(package: P, versions: VS, dep: (P, VS)) -> Self { let (p2, set2) = dep; Self { package_terms: if set2 == VS::empty() { diff --git a/src/internal/mod.rs b/src/internal/mod.rs index 643634f3..fd5ed9ba 100644 --- a/src/internal/mod.rs +++ b/src/internal/mod.rs @@ -10,8 +10,11 @@ mod small_map; mod small_vec; pub(crate) use arena::{Arena, Id}; -pub(crate) use core::State; -pub(crate) use incompatibility::{IncompDpId, IncompId, Incompatibility, Relation}; +pub(crate) use incompatibility::{IncompDpId, IncompId, Relation}; pub(crate) use partial_solution::{DecisionLevel, PartialSolution, SatisfierSearch}; pub(crate) use small_map::SmallMap; pub(crate) use small_vec::SmallVec; + +// uv-specific additions +pub use core::State; +pub use incompatibility::{Incompatibility, Kind}; diff --git a/src/internal/partial_solution.rs b/src/internal/partial_solution.rs index 44795582..52898ded 100644 --- a/src/internal/partial_solution.rs +++ b/src/internal/partial_solution.rs @@ -9,8 +9,7 @@ use std::hash::BuildHasherDefault; use priority_queue::PriorityQueue; use rustc_hash::FxHasher; -use super::small_vec::SmallVec; -use crate::internal::{Arena, IncompDpId, IncompId, Incompatibility, Relation, SmallMap}; +use crate::internal::{Arena, IncompDpId, IncompId, Incompatibility, Relation, SmallMap, SmallVec}; use crate::{DependencyProvider, Package, SelectedDependencies, Term, VersionSet}; type FnvIndexMap = indexmap::IndexMap>; @@ -27,7 +26,7 @@ impl DecisionLevel { /// The partial solution contains all package assignments, /// organized by package and historically ordered. #[derive(Clone, Debug)] -pub(crate) struct PartialSolution { +pub struct PartialSolution { next_global_index: u32, current_decision_level: DecisionLevel, /// `package_assignments` is primarily a HashMap from a package to its @@ -158,7 +157,7 @@ impl PartialSolution { } /// Add a decision. - pub(crate) fn add_decision(&mut self, package: DP::P, version: DP::V) { + pub fn add_decision(&mut self, package: DP::P, version: DP::V) { // Check that add_decision is never used in the wrong context. if cfg!(debug_assertions) { match self.package_assignments.get_mut(&package) { @@ -257,7 +256,7 @@ impl PartialSolution { } } - pub(crate) fn pick_highest_priority_pkg( + pub fn pick_highest_priority_pkg( &mut self, prioritizer: impl Fn(&DP::P, &DP::VS) -> DP::Priority, ) -> Option { @@ -288,7 +287,7 @@ impl PartialSolution { /// If a partial solution has, for every positive derivation, /// a corresponding decision that satisfies that assignment, /// it's a total solution and version solving has succeeded. - pub(crate) fn extract_solution(&self) -> SelectedDependencies { + pub fn extract_solution(&self) -> SelectedDependencies { self.package_assignments .iter() .take(self.current_decision_level.0 as usize) @@ -398,7 +397,7 @@ impl PartialSolution { } /// Retrieve intersection of terms related to package. - pub(crate) fn term_intersection_for_package(&self, package: &DP::P) -> Option<&Term> { + pub fn term_intersection_for_package(&self, package: &DP::P) -> Option<&Term> { self.package_assignments .get(package) .map(|pa| pa.assignments_intersection.term()) diff --git a/src/lib.rs b/src/lib.rs index 498b5907..159c7410 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -234,4 +234,7 @@ pub use version_ranges::Ranges; pub use version_ranges::Ranges as Range; pub use version_set::VersionSet; +// uv-specific additions +pub use internal::{Incompatibility, Kind, State}; + mod internal; diff --git a/src/term.rs b/src/term.rs index f8d51b9e..ec7a7066 100644 --- a/src/term.rs +++ b/src/term.rs @@ -72,7 +72,7 @@ impl Term { /// 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"),