From 3624c3b2f2be58b834abdd3f0efe14a7a121f1ba Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Tue, 3 Dec 2024 09:19:14 -0500 Subject: [PATCH] Allow `Ranges::contains` to accept (e.g.) `&str` for `Ranges` (#35) ## Summary This PR borrows a trick from [HashMap](https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.contains_key) to enable users to pass (e.g.) `&str` to `Ranges::contains`, given `Ranges`. --- src/internal/arena.rs | 12 +++++++++--- src/internal/core.rs | 2 +- src/solver.rs | 2 +- version-ranges/src/lib.rs | 24 ++++++++++++++++-------- 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/internal/arena.rs b/src/internal/arena.rs index 9648ff15..426852a6 100644 --- a/src/internal/arena.rs +++ b/src/internal/arena.rs @@ -150,9 +150,7 @@ impl fmt::Debug for HashArena { impl HashArena { pub fn new() -> Self { - HashArena { - data: FnvIndexSet::default(), - } + Self::default() } pub fn alloc(&mut self, value: T) -> Id { @@ -161,6 +159,14 @@ impl HashArena { } } +impl Default for HashArena { + fn default() -> Self { + Self { + data: FnvIndexSet::default(), + } + } +} + impl Index> for HashArena { type Output = T; fn index(&self, id: Id) -> &T { diff --git a/src/internal/core.rs b/src/internal/core.rs index a476ec16..26a699d9 100644 --- a/src/internal/core.rs +++ b/src/internal/core.rs @@ -83,7 +83,7 @@ impl State { let dep_incompats = self.add_incompatibility_from_dependencies(package, version.clone(), dependencies); self.partial_solution.add_package_version_incompatibilities( - package.clone(), + package, version.clone(), dep_incompats, &self.incompatibility_store, diff --git a/src/solver.rs b/src/solver.rs index 29d475d2..fbbf3ebe 100644 --- a/src/solver.rs +++ b/src/solver.rs @@ -171,7 +171,7 @@ pub fn resolve( }; // Add that package and version if the dependencies are not problematic. - state.add_package_version_dependencies(p.clone(), v.clone(), dependencies); + state.add_package_version_dependencies(p, v.clone(), dependencies); } else { // `dep_incompats` are already in `incompatibilities` so we know there are not satisfied // terms and can add the decision directly. diff --git a/version-ranges/src/lib.rs b/version-ranges/src/lib.rs index baac7bae..f0842858 100644 --- a/version-ranges/src/lib.rs +++ b/version-ranges/src/lib.rs @@ -229,7 +229,11 @@ impl Ranges { } /// Returns true if self contains the specified value. - pub fn contains(&self, version: &V) -> bool { + pub fn contains(&self, version: &Q) -> bool + where + V: Borrow, + Q: ?Sized + PartialOrd, + { self.segments .binary_search_by(|segment| { // We have to reverse because we need the segment wrt to the version, while @@ -470,10 +474,14 @@ impl Ord for Ranges { /// ^ ^ ^ /// less equal greater /// ``` -fn within_bounds(version: &V, segment: &Interval) -> Ordering { +fn within_bounds(version: &Q, segment: &Interval) -> Ordering +where + V: Borrow, + Q: ?Sized + PartialOrd, +{ let below_lower_bound = match segment { - (Excluded(start), _) => version <= start, - (Included(start), _) => version < start, + (Excluded(start), _) => version <= start.borrow(), + (Included(start), _) => version < start.borrow(), (Unbounded, _) => false, }; if below_lower_bound { @@ -481,8 +489,8 @@ fn within_bounds(version: &V, segment: &Interval) -> Ordering } let below_upper_bound = match segment { (_, Unbounded) => true, - (_, Included(end)) => version <= end, - (_, Excluded(end)) => version < end, + (_, Included(end)) => version <= end.borrow(), + (_, Excluded(end)) => version < end.borrow(), }; if below_upper_bound { return Ordering::Equal; @@ -1304,7 +1312,7 @@ pub mod tests { #[test] fn always_contains_exact(version in version_strat()) { - assert!(Ranges::singleton(version).contains(&version)); + assert!(Ranges::::singleton(version).contains(&version)); } #[test] @@ -1326,7 +1334,7 @@ pub mod tests { #[test] fn from_range_bounds(range in any::<(Bound, Bound)>(), version in version_strat()) { - let rv: Ranges<_> = Ranges::from_range_bounds(range); + let rv: Ranges<_> = Ranges::::from_range_bounds(range); assert_eq!(range.contains(&version), rv.contains(&version)); }