Skip to content

Commit 51ae2ad

Browse files
committed
Move offline provider into a separate module
1 parent 8a29d57 commit 51ae2ad

File tree

3 files changed

+121
-116
lines changed

3 files changed

+121
-116
lines changed

src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@
212212

213213
mod error;
214214
mod package;
215+
mod provider;
215216
mod report;
216217
mod solver;
217218
mod term;
@@ -221,11 +222,12 @@ mod version_set;
221222

222223
pub use error::{NoSolutionError, PubGrubError};
223224
pub use package::Package;
225+
pub use provider::OfflineDependencyProvider;
224226
pub use report::{
225227
DefaultStringReportFormatter, DefaultStringReporter, DerivationTree, Derived, External,
226228
ReportFormatter, Reporter,
227229
};
228-
pub use solver::{resolve, Dependencies, DependencyProvider, OfflineDependencyProvider};
230+
pub use solver::{resolve, Dependencies, DependencyProvider};
229231
pub use term::Term;
230232
pub use type_aliases::{DependencyConstraints, Map, SelectedDependencies, Set};
231233
pub use version::{SemanticVersion, VersionParseError};

src/provider.rs

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
use std::cmp::Reverse;
2+
use std::collections::BTreeMap;
3+
use std::convert::Infallible;
4+
5+
use crate::{Dependencies, DependencyConstraints, DependencyProvider, Map, Package, VersionSet};
6+
7+
/// A basic implementation of [DependencyProvider].
8+
#[derive(Debug, Clone, Default)]
9+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10+
#[cfg_attr(
11+
feature = "serde",
12+
serde(bound(
13+
serialize = "VS::V: serde::Serialize, VS: serde::Serialize, P: serde::Serialize",
14+
deserialize = "VS::V: serde::Deserialize<'de>, VS: serde::Deserialize<'de>, P: serde::Deserialize<'de>"
15+
))
16+
)]
17+
#[cfg_attr(feature = "serde", serde(transparent))]
18+
pub struct OfflineDependencyProvider<P: Package, VS: VersionSet> {
19+
dependencies: Map<P, BTreeMap<VS::V, DependencyConstraints<P, VS>>>,
20+
}
21+
22+
impl<P: Package, VS: VersionSet> OfflineDependencyProvider<P, VS> {
23+
/// Creates an empty OfflineDependencyProvider with no dependencies.
24+
pub fn new() -> Self {
25+
Self {
26+
dependencies: Map::default(),
27+
}
28+
}
29+
30+
/// Registers the dependencies of a package and version pair.
31+
/// Dependencies must be added with a single call to
32+
/// [add_dependencies](OfflineDependencyProvider::add_dependencies).
33+
/// All subsequent calls to
34+
/// [add_dependencies](OfflineDependencyProvider::add_dependencies) for a given
35+
/// package version pair will replace the dependencies by the new ones.
36+
///
37+
/// The API does not allow to add dependencies one at a time to uphold an assumption that
38+
/// [OfflineDependencyProvider.get_dependencies(p, v)](OfflineDependencyProvider::get_dependencies)
39+
/// provides all dependencies of a given package (p) and version (v) pair.
40+
pub fn add_dependencies<I: IntoIterator<Item = (P, VS)>>(
41+
&mut self,
42+
package: P,
43+
version: impl Into<VS::V>,
44+
dependencies: I,
45+
) {
46+
let package_deps = dependencies.into_iter().collect();
47+
let v = version.into();
48+
*self
49+
.dependencies
50+
.entry(package)
51+
.or_default()
52+
.entry(v)
53+
.or_default() = package_deps;
54+
}
55+
56+
/// Lists packages that have been saved.
57+
pub fn packages(&self) -> impl Iterator<Item = &P> {
58+
self.dependencies.keys()
59+
}
60+
61+
/// Lists versions of saved packages in sorted order.
62+
/// Returns [None] if no information is available regarding that package.
63+
pub fn versions(&self, package: &P) -> Option<impl Iterator<Item = &VS::V>> {
64+
self.dependencies.get(package).map(|k| k.keys())
65+
}
66+
67+
/// Lists dependencies of a given package and version.
68+
/// Returns [None] if no information is available regarding that package and version pair.
69+
fn dependencies(&self, package: &P, version: &VS::V) -> Option<DependencyConstraints<P, VS>> {
70+
self.dependencies.get(package)?.get(version).cloned()
71+
}
72+
}
73+
74+
/// An implementation of [DependencyProvider] that
75+
/// contains all dependency information available in memory.
76+
/// Currently packages are picked with the fewest versions contained in the constraints first.
77+
/// But, that may change in new versions if better heuristics are found.
78+
/// Versions are picked with the newest versions first.
79+
impl<P: Package, VS: VersionSet> DependencyProvider for OfflineDependencyProvider<P, VS> {
80+
type P = P;
81+
type V = VS::V;
82+
type VS = VS;
83+
type M = String;
84+
85+
type Err = Infallible;
86+
87+
fn choose_version(&self, package: &P, range: &VS) -> Result<Option<VS::V>, Infallible> {
88+
Ok(self
89+
.dependencies
90+
.get(package)
91+
.and_then(|versions| versions.keys().rev().find(|v| range.contains(v)).cloned()))
92+
}
93+
94+
type Priority = Reverse<usize>;
95+
fn prioritize(&self, package: &P, range: &VS) -> Self::Priority {
96+
Reverse(
97+
self.dependencies
98+
.get(package)
99+
.map(|versions| versions.keys().filter(|v| range.contains(v)).count())
100+
.unwrap_or(0),
101+
)
102+
}
103+
104+
fn get_dependencies(
105+
&self,
106+
package: &P,
107+
version: &VS::V,
108+
) -> Result<Dependencies<P, VS, Self::M>, Infallible> {
109+
Ok(match self.dependencies(package, version) {
110+
None => {
111+
Dependencies::Unavailable("its dependencies could not be determined".to_string())
112+
}
113+
Some(dependencies) => Dependencies::Available(dependencies),
114+
})
115+
}
116+
}

src/solver.rs

Lines changed: 2 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,7 @@
5959
//! to satisfy the dependencies of that package and version pair.
6060
//! If there is no solution, the reason will be provided as clear as possible.
6161
62-
use std::cmp::Reverse;
63-
use std::collections::{BTreeMap, BTreeSet as Set};
64-
use std::convert::Infallible;
62+
use std::collections::BTreeSet as Set;
6563
use std::error::Error;
6664
use std::fmt::{Debug, Display};
6765

@@ -244,7 +242,7 @@ pub trait DependencyProvider {
244242
/// The type returned from `prioritize`. The resolver does not care what type this is
245243
/// as long as it can pick a largest one and clone it.
246244
///
247-
/// [Reverse] can be useful if you want to pick the package with
245+
/// [`Reverse`](std::cmp::Reverse) can be useful if you want to pick the package with
248246
/// the fewest versions that match the outstanding constraint.
249247
type Priority: Ord + Clone;
250248

@@ -280,114 +278,3 @@ pub trait DependencyProvider {
280278
Ok(())
281279
}
282280
}
283-
284-
/// A basic implementation of [DependencyProvider].
285-
#[derive(Debug, Clone, Default)]
286-
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
287-
#[cfg_attr(
288-
feature = "serde",
289-
serde(bound(
290-
serialize = "VS::V: serde::Serialize, VS: serde::Serialize, P: serde::Serialize",
291-
deserialize = "VS::V: serde::Deserialize<'de>, VS: serde::Deserialize<'de>, P: serde::Deserialize<'de>"
292-
))
293-
)]
294-
#[cfg_attr(feature = "serde", serde(transparent))]
295-
pub struct OfflineDependencyProvider<P: Package, VS: VersionSet> {
296-
dependencies: Map<P, BTreeMap<VS::V, DependencyConstraints<P, VS>>>,
297-
}
298-
299-
impl<P: Package, VS: VersionSet> OfflineDependencyProvider<P, VS> {
300-
/// Creates an empty OfflineDependencyProvider with no dependencies.
301-
pub fn new() -> Self {
302-
Self {
303-
dependencies: Map::default(),
304-
}
305-
}
306-
307-
/// Registers the dependencies of a package and version pair.
308-
/// Dependencies must be added with a single call to
309-
/// [add_dependencies](OfflineDependencyProvider::add_dependencies).
310-
/// All subsequent calls to
311-
/// [add_dependencies](OfflineDependencyProvider::add_dependencies) for a given
312-
/// package version pair will replace the dependencies by the new ones.
313-
///
314-
/// The API does not allow to add dependencies one at a time to uphold an assumption that
315-
/// [OfflineDependencyProvider.get_dependencies(p, v)](OfflineDependencyProvider::get_dependencies)
316-
/// provides all dependencies of a given package (p) and version (v) pair.
317-
pub fn add_dependencies<I: IntoIterator<Item = (P, VS)>>(
318-
&mut self,
319-
package: P,
320-
version: impl Into<VS::V>,
321-
dependencies: I,
322-
) {
323-
let package_deps = dependencies.into_iter().collect();
324-
let v = version.into();
325-
*self
326-
.dependencies
327-
.entry(package)
328-
.or_default()
329-
.entry(v)
330-
.or_default() = package_deps;
331-
}
332-
333-
/// Lists packages that have been saved.
334-
pub fn packages(&self) -> impl Iterator<Item = &P> {
335-
self.dependencies.keys()
336-
}
337-
338-
/// Lists versions of saved packages in sorted order.
339-
/// Returns [None] if no information is available regarding that package.
340-
pub fn versions(&self, package: &P) -> Option<impl Iterator<Item = &VS::V>> {
341-
self.dependencies.get(package).map(|k| k.keys())
342-
}
343-
344-
/// Lists dependencies of a given package and version.
345-
/// Returns [None] if no information is available regarding that package and version pair.
346-
fn dependencies(&self, package: &P, version: &VS::V) -> Option<DependencyConstraints<P, VS>> {
347-
self.dependencies.get(package)?.get(version).cloned()
348-
}
349-
}
350-
351-
/// An implementation of [DependencyProvider] that
352-
/// contains all dependency information available in memory.
353-
/// Currently packages are picked with the fewest versions contained in the constraints first.
354-
/// But, that may change in new versions if better heuristics are found.
355-
/// Versions are picked with the newest versions first.
356-
impl<P: Package, VS: VersionSet> DependencyProvider for OfflineDependencyProvider<P, VS> {
357-
type P = P;
358-
type V = VS::V;
359-
type VS = VS;
360-
type M = String;
361-
362-
type Err = Infallible;
363-
364-
fn choose_version(&self, package: &P, range: &VS) -> Result<Option<VS::V>, Infallible> {
365-
Ok(self
366-
.dependencies
367-
.get(package)
368-
.and_then(|versions| versions.keys().rev().find(|v| range.contains(v)).cloned()))
369-
}
370-
371-
type Priority = Reverse<usize>;
372-
fn prioritize(&self, package: &P, range: &VS) -> Self::Priority {
373-
Reverse(
374-
self.dependencies
375-
.get(package)
376-
.map(|versions| versions.keys().filter(|v| range.contains(v)).count())
377-
.unwrap_or(0),
378-
)
379-
}
380-
381-
fn get_dependencies(
382-
&self,
383-
package: &P,
384-
version: &VS::V,
385-
) -> Result<Dependencies<P, VS, Self::M>, Infallible> {
386-
Ok(match self.dependencies(package, version) {
387-
None => {
388-
Dependencies::Unavailable("its dependencies could not be determined".to_string())
389-
}
390-
Some(dependencies) => Dependencies::Available(dependencies),
391-
})
392-
}
393-
}

0 commit comments

Comments
 (0)