Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
run: cargo build --verbose

- name: Run tests
run: cargo test --features=serde --verbose
run: cargo test --verbose

clippy:
name: No warnings from Clippy
Expand Down
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@ include = ["Cargo.toml", "LICENSE", "README.md", "src/**", "tests/**", "examples
thiserror = "1.0"
rustc-hash = "1.1.0"
serde = { version = "1.0", features = ["derive"], optional = true }
log = { version = "0.4.14", default-features = false } # for debug logs in tests

[dev-dependencies]
proptest = "0.10.1"
ron = "0.6"
varisat = "0.2.2"
criterion = "0.3"
env_logger = "0.9.0"

[[bench]]
name = "large_case"
Expand Down
7 changes: 4 additions & 3 deletions examples/branching_error_reporting.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
// SPDX-License-Identifier: MPL-2.0

use pubgrub::error::PubGrubError;
use pubgrub::range::Range;
use pubgrub::range_trait::Range;
use pubgrub::report::{DefaultStringReporter, Reporter};
use pubgrub::solver::{resolve, OfflineDependencyProvider};
use pubgrub::version::SemanticVersion;
use pubgrub::version_trait::{SemanticInterval, SemanticVersion};

// https://github.com/dart-lang/pub/blob/master/doc/solver.md#branching-error-reporting
fn main() {
let mut dependency_provider = OfflineDependencyProvider::<&str, SemanticVersion>::new();
let mut dependency_provider =
OfflineDependencyProvider::<&str, SemanticInterval, SemanticVersion>::new();
#[rustfmt::skip]
// root 1.0.0 depends on foo ^1.0.0
dependency_provider.add_dependencies(
Expand Down
28 changes: 18 additions & 10 deletions examples/caching_dependency_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,25 @@ use std::cell::RefCell;
use std::error::Error;

use pubgrub::package::Package;
use pubgrub::range::Range;
use pubgrub::range_trait::Range;
use pubgrub::solver::{resolve, Dependencies, DependencyProvider, OfflineDependencyProvider};
use pubgrub::version::{NumberVersion, Version};
use pubgrub::version_trait::{Interval, NumberInterval, NumberVersion, Version};

// An example implementing caching dependency provider that will
// store queried dependencies in memory and check them before querying more from remote.
struct CachingDependencyProvider<P: Package, V: Version, DP: DependencyProvider<P, V>> {
struct CachingDependencyProvider<
P: Package,
I: Interval<V>,
V: Version,
DP: DependencyProvider<P, I, V>,
> {
remote_dependencies: DP,
cached_dependencies: RefCell<OfflineDependencyProvider<P, V>>,
cached_dependencies: RefCell<OfflineDependencyProvider<P, I, V>>,
}

impl<P: Package, V: Version, DP: DependencyProvider<P, V>> CachingDependencyProvider<P, V, DP> {
impl<P: Package, I: Interval<V>, V: Version, DP: DependencyProvider<P, I, V>>
CachingDependencyProvider<P, I, V, DP>
{
pub fn new(remote_dependencies_provider: DP) -> Self {
CachingDependencyProvider {
remote_dependencies: remote_dependencies_provider,
Expand All @@ -24,10 +31,10 @@ impl<P: Package, V: Version, DP: DependencyProvider<P, V>> CachingDependencyProv
}
}

impl<P: Package, V: Version, DP: DependencyProvider<P, V>> DependencyProvider<P, V>
for CachingDependencyProvider<P, V, DP>
impl<P: Package, I: Interval<V>, V: Version, DP: DependencyProvider<P, I, V>>
DependencyProvider<P, I, V> for CachingDependencyProvider<P, I, V, DP>
{
fn choose_package_version<T: std::borrow::Borrow<P>, U: std::borrow::Borrow<Range<V>>>(
fn choose_package_version<T: std::borrow::Borrow<P>, U: std::borrow::Borrow<Range<I, V>>>(
&self,
packages: impl Iterator<Item = (T, U)>,
) -> Result<(T, Option<V>), Box<dyn Error>> {
Expand All @@ -39,7 +46,7 @@ impl<P: Package, V: Version, DP: DependencyProvider<P, V>> DependencyProvider<P,
&self,
package: &P,
version: &V,
) -> Result<Dependencies<P, V>, Box<dyn Error>> {
) -> Result<Dependencies<P, I, V>, Box<dyn Error>> {
let mut cache = self.cached_dependencies.borrow_mut();
match cache.get_dependencies(package, version) {
Ok(Dependencies::Unknown) => {
Expand All @@ -65,7 +72,8 @@ impl<P: Package, V: Version, DP: DependencyProvider<P, V>> DependencyProvider<P,

fn main() {
// Simulating remote provider locally.
let mut remote_dependencies_provider = OfflineDependencyProvider::<&str, NumberVersion>::new();
let mut remote_dependencies_provider =
OfflineDependencyProvider::<&str, NumberInterval, NumberVersion>::new();

// Add dependencies as needed. Here only root package is added.
remote_dependencies_provider.add_dependencies("root", 1, Vec::new());
Expand Down
12 changes: 6 additions & 6 deletions examples/doc_interface.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
// SPDX-License-Identifier: MPL-2.0

use pubgrub::range::Range;
use pubgrub::range_trait::Range;
use pubgrub::solver::{resolve, OfflineDependencyProvider};
use pubgrub::version::NumberVersion;
use pubgrub::version_trait::{NumberInterval, NumberVersion};

// `root` depends on `menu` and `icons`
// `menu` depends on `dropdown`
// `dropdown` depends on `icons`
// `icons` has no dependency
#[rustfmt::skip]
fn main() {
let mut dependency_provider = OfflineDependencyProvider::<&str, NumberVersion>::new();
let mut dependency_provider = OfflineDependencyProvider::<&str, NumberInterval, NumberVersion>::new();
dependency_provider.add_dependencies(
"root", 1, vec![("menu", Range::any()), ("icons", Range::any())],
"root", 1, vec![("menu", Range::full()), ("icons", Range::full())],
);
dependency_provider.add_dependencies("menu", 1, vec![("dropdown", Range::any())]);
dependency_provider.add_dependencies("dropdown", 1, vec![("icons", Range::any())]);
dependency_provider.add_dependencies("menu", 1, vec![("dropdown", Range::full())]);
dependency_provider.add_dependencies("dropdown", 1, vec![("icons", Range::full())]);
dependency_provider.add_dependencies("icons", 1, vec![]);

// Run the algorithm.
Expand Down
22 changes: 11 additions & 11 deletions examples/doc_interface_error.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// SPDX-License-Identifier: MPL-2.0

use pubgrub::error::PubGrubError;
use pubgrub::range::Range;
use pubgrub::range_trait::Range;
use pubgrub::report::{DefaultStringReporter, Reporter};
use pubgrub::solver::{resolve, OfflineDependencyProvider};
use pubgrub::version::SemanticVersion;
use pubgrub::version_trait::{SemanticInterval, SemanticVersion};

// `root` depends on `menu`, `icons 1.0.0` and `intl 5.0.0`
// `menu 1.0.0` depends on `dropdown < 2.0.0`
Expand All @@ -15,12 +15,12 @@ use pubgrub::version::SemanticVersion;
// `intl` has no dependency
#[rustfmt::skip]
fn main() {
let mut dependency_provider = OfflineDependencyProvider::<&str, SemanticVersion>::new();
let mut dependency_provider = OfflineDependencyProvider::<&str, SemanticInterval, SemanticVersion>::new();
// Direct dependencies: menu and icons.
dependency_provider.add_dependencies("root", (1, 0, 0), vec![
("menu", Range::any()),
("icons", Range::exact((1, 0, 0))),
("intl", Range::exact((5, 0, 0))),
("menu", Range::full()),
("icons", Range::singleton((1, 0, 0))),
("intl", Range::singleton((5, 0, 0))),
]);

// Dependencies of the menu lib.
Expand All @@ -45,19 +45,19 @@ fn main() {

// Dependencies of the dropdown lib.
dependency_provider.add_dependencies("dropdown", (1, 8, 0), vec![
("intl", Range::exact((3, 0, 0))),
("intl", Range::singleton((3, 0, 0))),
]);
dependency_provider.add_dependencies("dropdown", (2, 0, 0), vec![
("icons", Range::exact((2, 0, 0))),
("icons", Range::singleton((2, 0, 0))),
]);
dependency_provider.add_dependencies("dropdown", (2, 1, 0), vec![
("icons", Range::exact((2, 0, 0))),
("icons", Range::singleton((2, 0, 0))),
]);
dependency_provider.add_dependencies("dropdown", (2, 2, 0), vec![
("icons", Range::exact((2, 0, 0))),
("icons", Range::singleton((2, 0, 0))),
]);
dependency_provider.add_dependencies("dropdown", (2, 3, 0), vec![
("icons", Range::exact((2, 0, 0))),
("icons", Range::singleton((2, 0, 0))),
]);

// Icons have no dependencies.
Expand Down
18 changes: 9 additions & 9 deletions examples/doc_interface_semantic.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// SPDX-License-Identifier: MPL-2.0

use pubgrub::error::PubGrubError;
use pubgrub::range::Range;
use pubgrub::range_trait::Range;
use pubgrub::report::{DefaultStringReporter, Reporter};
use pubgrub::solver::{resolve, OfflineDependencyProvider};
use pubgrub::version::SemanticVersion;
use pubgrub::version_trait::{SemanticInterval, SemanticVersion};

// `root` depends on `menu` and `icons 1.0.0`
// `menu 1.0.0` depends on `dropdown < 2.0.0`
Expand All @@ -14,11 +14,11 @@ use pubgrub::version::SemanticVersion;
// `icons` has no dependency
#[rustfmt::skip]
fn main() {
let mut dependency_provider = OfflineDependencyProvider::<&str, SemanticVersion>::new();
let mut dependency_provider = OfflineDependencyProvider::<&str, SemanticInterval, SemanticVersion>::new();
// Direct dependencies: menu and icons.
dependency_provider.add_dependencies("root", (1, 0, 0), vec![
("menu", Range::any()),
("icons", Range::exact((1, 0, 0))),
("menu", Range::full()),
("icons", Range::singleton((1, 0, 0))),
]);

// Dependencies of the menu lib.
Expand All @@ -44,16 +44,16 @@ fn main() {
// Dependencies of the dropdown lib.
dependency_provider.add_dependencies("dropdown", (1, 8, 0), vec![]);
dependency_provider.add_dependencies("dropdown", (2, 0, 0), vec![
("icons", Range::exact((2, 0, 0))),
("icons", Range::singleton((2, 0, 0))),
]);
dependency_provider.add_dependencies("dropdown", (2, 1, 0), vec![
("icons", Range::exact((2, 0, 0))),
("icons", Range::singleton((2, 0, 0))),
]);
dependency_provider.add_dependencies("dropdown", (2, 2, 0), vec![
("icons", Range::exact((2, 0, 0))),
("icons", Range::singleton((2, 0, 0))),
]);
dependency_provider.add_dependencies("dropdown", (2, 3, 0), vec![
("icons", Range::exact((2, 0, 0))),
("icons", Range::singleton((2, 0, 0))),
]);

// Icons has no dependency.
Expand Down
7 changes: 4 additions & 3 deletions examples/linear_error_reporting.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
// SPDX-License-Identifier: MPL-2.0

use pubgrub::error::PubGrubError;
use pubgrub::range::Range;
use pubgrub::range_trait::Range;
use pubgrub::report::{DefaultStringReporter, Reporter};
use pubgrub::solver::{resolve, OfflineDependencyProvider};
use pubgrub::version::SemanticVersion;
use pubgrub::version_trait::{SemanticInterval, SemanticVersion};

// https://github.com/dart-lang/pub/blob/master/doc/solver.md#linear-error-reporting
fn main() {
let mut dependency_provider = OfflineDependencyProvider::<&str, SemanticVersion>::new();
let mut dependency_provider =
OfflineDependencyProvider::<&str, SemanticInterval, SemanticVersion>::new();
#[rustfmt::skip]
// root 1.0.0 depends on foo ^1.0.0 and baz ^1.0.0
dependency_provider.add_dependencies(
Expand Down
7 changes: 4 additions & 3 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ use thiserror::Error;

use crate::package::Package;
use crate::report::DerivationTree;
use crate::version::Version;
use crate::version_trait::{Interval, Version};
use std::fmt::Debug;

/// Errors that may occur while solving dependencies.
#[derive(Error, Debug)]
pub enum PubGrubError<P: Package, V: Version> {
pub enum PubGrubError<P: Package, I: Interval<V> + Debug, V: Version> {
/// There is no solution for this set of dependencies.
#[error("No solution")]
NoSolution(DerivationTree<P, V>),
NoSolution(DerivationTree<P, I, V>),

/// Error arising when the implementer of
/// [DependencyProvider](crate::solver::DependencyProvider)
Expand Down
Loading