Skip to content

Commit

Permalink
Split version ranges into their own crate (pubgrub-rs#262)
Browse files Browse the repository at this point in the history
* Split version ranges into their own crate

* polish

* Rename to `Ranges`

* Doc

* Use union feature for smallvec

> This feature requires Rust 1.49.

> When the union feature is enabled smallvec will track its state (inline or spilled) without the use of an enum tag, reducing the size of the smallvec by one machine word. This means that there is potentially no space overhead compared to Vec. Note that smallvec can still be larger than Vec if the inline buffer is larger than two machine words.

* Use `SmallVec<[Interval<V>; 1]>` for better performance

* Move comments.

* Add alias to avoid breaking change
  • Loading branch information
konstin authored Oct 29, 2024
1 parent be52667 commit 8c37699
Show file tree
Hide file tree
Showing 21 changed files with 431 additions and 393 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- run: cargo build --verbose
- run: cargo test --features=serde --verbose
- run: cargo build --verbose --workspace
- run: cargo test --all-features --workspace --verbose

clippy:
name: No warnings from Clippy
Expand All @@ -30,7 +30,7 @@ jobs:
- name: Check Clippy lints
env:
RUSTFLAGS: -D warnings
run: cargo clippy
run: cargo clippy --workspace

check_formatting:
name: Source code is formatted
Expand All @@ -51,4 +51,4 @@ jobs:
- name: Check documentation
env:
RUSTDOCFLAGS: -D warnings
run: cargo doc --no-deps --document-private-items
run: cargo doc --workspace --no-deps --document-private-items
14 changes: 14 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 12 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# SPDX-License-Identifier: MPL-2.0

[workspace]
members = ["version-ranges"]

[package]
name = "pubgrub"
version = "0.2.1"
Expand All @@ -21,18 +24,23 @@ include = ["Cargo.toml", "LICENSE", "README.md", "src/**", "tests/**", "examples

[dependencies]
indexmap = "2.5.0"
log = "0.4.22" # for debug logs in tests
priority-queue = "2.1.1"
thiserror = "1.0"
rustc-hash = ">=1.0.0, <3.0.0"
serde = { version = "1.0", features = ["derive"], optional = true }
log = "0.4.22" # for debug logs in tests
thiserror = "1.0"
version-ranges = { version = "0.1.0", path = "version-ranges" }

[dev-dependencies]
criterion = "0.5"
env_logger = "0.11.5"
proptest = "1.5.0"
ron = "=0.9.0-alpha.0"
varisat = "0.2.2"
criterion = "0.5"
env_logger = "0.11.5"
version-ranges = { version = "0.1.0", path = "version-ranges", features = ["proptest"] }

[features]
serde = ["dep:serde", "version-ranges/serde"]

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

use pubgrub::{
resolve, DefaultStringReporter, OfflineDependencyProvider, PubGrubError, Range, Reporter,
resolve, DefaultStringReporter, OfflineDependencyProvider, PubGrubError, Ranges, Reporter,
SemanticVersion,
};

type SemVS = Range<SemanticVersion>;
type SemVS = Ranges<SemanticVersion>;

// https://github.com/dart-lang/pub/blob/master/doc/solver.md#branching-error-reporting
fn main() {
Expand All @@ -14,31 +14,31 @@ fn main() {
// root 1.0.0 depends on foo ^1.0.0
dependency_provider.add_dependencies(
"root", (1, 0, 0),
[("foo", Range::from_range_bounds((1, 0, 0)..(2, 0, 0)))],
[("foo", Ranges::from_range_bounds((1, 0, 0)..(2, 0, 0)))],
);
#[rustfmt::skip]
// foo 1.0.0 depends on a ^1.0.0 and b ^1.0.0
dependency_provider.add_dependencies(
"foo", (1, 0, 0),
[
("a", Range::from_range_bounds((1, 0, 0)..(2, 0, 0))),
("b", Range::from_range_bounds((1, 0, 0)..(2, 0, 0))),
("a", Ranges::from_range_bounds((1, 0, 0)..(2, 0, 0))),
("b", Ranges::from_range_bounds((1, 0, 0)..(2, 0, 0))),
],
);
#[rustfmt::skip]
// foo 1.1.0 depends on x ^1.0.0 and y ^1.0.0
dependency_provider.add_dependencies(
"foo", (1, 1, 0),
[
("x", Range::from_range_bounds((1, 0, 0)..(2, 0, 0))),
("y", Range::from_range_bounds((1, 0, 0)..(2, 0, 0))),
("x", Ranges::from_range_bounds((1, 0, 0)..(2, 0, 0))),
("y", Ranges::from_range_bounds((1, 0, 0)..(2, 0, 0))),
],
);
#[rustfmt::skip]
// a 1.0.0 depends on b ^2.0.0
dependency_provider.add_dependencies(
"a", (1, 0, 0),
[("b", Range::from_range_bounds((2, 0, 0)..(3, 0, 0)))],
[("b", Ranges::from_range_bounds((2, 0, 0)..(3, 0, 0)))],
);
// b 1.0.0 and 2.0.0 have no dependencies.
dependency_provider.add_dependencies("b", (1, 0, 0), []);
Expand All @@ -47,7 +47,7 @@ fn main() {
// x 1.0.0 depends on y ^2.0.0.
dependency_provider.add_dependencies(
"x", (1, 0, 0),
[("y", Range::from_range_bounds((2, 0, 0)..(3, 0, 0)))],
[("y", Ranges::from_range_bounds((2, 0, 0)..(3, 0, 0)))],
);
// y 1.0.0 and 2.0.0 have no dependencies.
dependency_provider.add_dependencies("y", (1, 0, 0), []);
Expand Down
12 changes: 6 additions & 6 deletions examples/caching_dependency_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

use std::cell::RefCell;

use pubgrub::{resolve, Dependencies, DependencyProvider, OfflineDependencyProvider, Range};
use pubgrub::{resolve, Dependencies, DependencyProvider, OfflineDependencyProvider, Ranges};

type NumVS = Range<u32>;
type NumVS = Ranges<u32>;

// An example implementing caching dependency provider that will
// store queried dependencies in memory and check them before querying more from remote.
Expand Down Expand Up @@ -51,14 +51,14 @@ impl<DP: DependencyProvider<M = String>> DependencyProvider for CachingDependenc
}
}

fn choose_version(&self, package: &DP::P, range: &DP::VS) -> Result<Option<DP::V>, DP::Err> {
self.remote_dependencies.choose_version(package, range)
fn choose_version(&self, package: &DP::P, ranges: &DP::VS) -> Result<Option<DP::V>, DP::Err> {
self.remote_dependencies.choose_version(package, ranges)
}

type Priority = DP::Priority;

fn prioritize(&self, package: &DP::P, range: &DP::VS) -> Self::Priority {
self.remote_dependencies.prioritize(package, range)
fn prioritize(&self, package: &DP::P, ranges: &DP::VS) -> Self::Priority {
self.remote_dependencies.prioritize(package, ranges)
}

type Err = DP::Err;
Expand Down
10 changes: 5 additions & 5 deletions examples/doc_interface.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: MPL-2.0

use pubgrub::{resolve, OfflineDependencyProvider, Range};
use pubgrub::{resolve, OfflineDependencyProvider, Ranges};

type NumVS = Range<u32>;
type NumVS = Ranges<u32>;

// `root` depends on `menu` and `icons`
// `menu` depends on `dropdown`
Expand All @@ -12,10 +12,10 @@ type NumVS = Range<u32>;
fn main() {
let mut dependency_provider = OfflineDependencyProvider::<&str, NumVS>::new();
dependency_provider.add_dependencies(
"root", 1u32, [("menu", Range::full()), ("icons", Range::full())],
"root", 1u32, [("menu", Ranges::full()), ("icons", Ranges::full())],
);
dependency_provider.add_dependencies("menu", 1u32, [("dropdown", Range::full())]);
dependency_provider.add_dependencies("dropdown", 1u32, [("icons", Range::full())]);
dependency_provider.add_dependencies("menu", 1u32, [("dropdown", Ranges::full())]);
dependency_provider.add_dependencies("dropdown", 1u32, [("icons", Ranges::full())]);
dependency_provider.add_dependencies("icons", 1u32, []);

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

use pubgrub::{
resolve, DefaultStringReporter, OfflineDependencyProvider, PubGrubError, Range, Reporter,
resolve, DefaultStringReporter, OfflineDependencyProvider, PubGrubError, Ranges, Reporter,
SemanticVersion,
};

type SemVS = Range<SemanticVersion>;
type SemVS = Ranges<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 @@ -19,46 +19,46 @@ fn main() {
let mut dependency_provider = OfflineDependencyProvider::<&str, SemVS>::new();
// Direct dependencies: menu and icons.
dependency_provider.add_dependencies("root", (1, 0, 0), [
("menu", Range::full()),
("icons", Range::singleton((1, 0, 0))),
("intl", Range::singleton((5, 0, 0))),
("menu", Ranges::full()),
("icons", Ranges::singleton((1, 0, 0))),
("intl", Ranges::singleton((5, 0, 0))),
]);

// Dependencies of the menu lib.
dependency_provider.add_dependencies("menu", (1, 0, 0), [
("dropdown", Range::from_range_bounds(..(2, 0, 0))),
("dropdown", Ranges::from_range_bounds(..(2, 0, 0))),
]);
dependency_provider.add_dependencies("menu", (1, 1, 0), [
("dropdown", Range::from_range_bounds((2, 0, 0)..)),
("dropdown", Ranges::from_range_bounds((2, 0, 0)..)),
]);
dependency_provider.add_dependencies("menu", (1, 2, 0), [
("dropdown", Range::from_range_bounds((2, 0, 0)..)),
("dropdown", Ranges::from_range_bounds((2, 0, 0)..)),
]);
dependency_provider.add_dependencies("menu", (1, 3, 0), [
("dropdown", Range::from_range_bounds((2, 0, 0)..)),
("dropdown", Ranges::from_range_bounds((2, 0, 0)..)),
]);
dependency_provider.add_dependencies("menu", (1, 4, 0), [
("dropdown", Range::from_range_bounds((2, 0, 0)..)),
("dropdown", Ranges::from_range_bounds((2, 0, 0)..)),
]);
dependency_provider.add_dependencies("menu", (1, 5, 0), [
("dropdown", Range::from_range_bounds((2, 0, 0)..)),
("dropdown", Ranges::from_range_bounds((2, 0, 0)..)),
]);

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

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

use pubgrub::{
resolve, DefaultStringReporter, OfflineDependencyProvider, PubGrubError, Range, Reporter,
resolve, DefaultStringReporter, OfflineDependencyProvider, PubGrubError, Ranges, Reporter,
SemanticVersion,
};

type SemVS = Range<SemanticVersion>;
type SemVS = Ranges<SemanticVersion>;

// `root` depends on `menu` and `icons 1.0.0`
// `menu 1.0.0` depends on `dropdown < 2.0.0`
Expand All @@ -18,43 +18,43 @@ fn main() {
let mut dependency_provider = OfflineDependencyProvider::<&str, SemVS>::new();
// Direct dependencies: menu and icons.
dependency_provider.add_dependencies("root", (1, 0, 0), [
("menu", Range::full()),
("icons", Range::singleton((1, 0, 0))),
("menu", Ranges::full()),
("icons", Ranges::singleton((1, 0, 0))),
]);

// Dependencies of the menu lib.
dependency_provider.add_dependencies("menu", (1, 0, 0), [
("dropdown", Range::from_range_bounds(..(2, 0, 0))),
("dropdown", Ranges::from_range_bounds(..(2, 0, 0))),
]);
dependency_provider.add_dependencies("menu", (1, 1, 0), [
("dropdown", Range::from_range_bounds((2, 0, 0)..)),
("dropdown", Ranges::from_range_bounds((2, 0, 0)..)),
]);
dependency_provider.add_dependencies("menu", (1, 2, 0), [
("dropdown", Range::from_range_bounds((2, 0, 0)..)),
("dropdown", Ranges::from_range_bounds((2, 0, 0)..)),
]);
dependency_provider.add_dependencies("menu", (1, 3, 0), [
("dropdown", Range::from_range_bounds((2, 0, 0)..)),
("dropdown", Ranges::from_range_bounds((2, 0, 0)..)),
]);
dependency_provider.add_dependencies("menu", (1, 4, 0), [
("dropdown", Range::from_range_bounds((2, 0, 0)..)),
("dropdown", Ranges::from_range_bounds((2, 0, 0)..)),
]);
dependency_provider.add_dependencies("menu", (1, 5, 0), [
("dropdown", Range::from_range_bounds((2, 0, 0)..)),
("dropdown", Ranges::from_range_bounds((2, 0, 0)..)),
]);

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

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

use pubgrub::{
resolve, DefaultStringReporter, OfflineDependencyProvider, PubGrubError, Range, Reporter,
resolve, DefaultStringReporter, OfflineDependencyProvider, PubGrubError, Ranges, Reporter,
SemanticVersion,
};

type SemVS = Range<SemanticVersion>;
type SemVS = Ranges<SemanticVersion>;

// https://github.com/dart-lang/pub/blob/master/doc/solver.md#linear-error-reporting
fn main() {
Expand All @@ -15,21 +15,21 @@ fn main() {
dependency_provider.add_dependencies(
"root", (1, 0, 0),
[
("foo", Range::from_range_bounds((1, 0, 0)..(2, 0, 0))),
("baz", Range::from_range_bounds((1, 0, 0)..(2, 0, 0))),
("foo", Ranges::from_range_bounds((1, 0, 0)..(2, 0, 0))),
("baz", Ranges::from_range_bounds((1, 0, 0)..(2, 0, 0))),
],
);
#[rustfmt::skip]
// foo 1.0.0 depends on bar ^2.0.0
dependency_provider.add_dependencies(
"foo", (1, 0, 0),
[("bar", Range::from_range_bounds((2, 0, 0)..(3, 0, 0)))],
[("bar", Ranges::from_range_bounds((2, 0, 0)..(3, 0, 0)))],
);
#[rustfmt::skip]
// bar 2.0.0 depends on baz ^3.0.0
dependency_provider.add_dependencies(
"bar", (2, 0, 0),
[("baz", Range::from_range_bounds((3, 0, 0)..(4, 0, 0)))],
[("baz", Ranges::from_range_bounds((3, 0, 0)..(4, 0, 0)))],
);
// baz 1.0.0 and 3.0.0 have no dependencies
dependency_provider.add_dependencies("baz", (1, 0, 0), []);
Expand Down
Loading

0 comments on commit 8c37699

Please sign in to comment.