From 4889c5ce4efff6ead5636d681afeab4d6f70cd08 Mon Sep 17 00:00:00 2001 From: al8n Date: Mon, 14 Oct 2024 16:57:41 +0800 Subject: [PATCH 1/4] Support `RangeBounds` for `T: Comparable` --- Cargo.toml | 4 ++-- src/lib.rs | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8fcf21a..84d0721 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "equivalent" -version = "1.0.1" -rust-version = "1.6" +version = "1.1.0" +rust-version = "1.28" license = "Apache-2.0 OR MIT" description = "Traits for key comparison in maps." repository = "https://github.com/cuviper/equivalent" diff --git a/src/lib.rs b/src/lib.rs index 09ba58d..19981ae 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -56,6 +56,11 @@ //! assert_eq!(q1.compare(&key), Ordering::Equal); //! assert_eq!(q2.compare(&key), Ordering::Less); //! assert_eq!(q3.compare(&key), Ordering::Greater); +//! +//! // You cannot do this with the `RangeBounds::contains` method. +//! // assert!((q1..q3).contains(key)); +//! // But you can do this with the `ComparableRangeBounds::compare_contains` method. +//! assert!((q1..q3).compare_contains(&key)); //! } //! ``` @@ -63,6 +68,7 @@ use core::borrow::Borrow; use core::cmp::Ordering; +use core::ops::{Bound, RangeBounds}; /// Key equivalence trait. /// @@ -111,3 +117,35 @@ where Ord::cmp(self, key.borrow()) } } + +/// `ComparableRangeBounds` is implemented as an extention to `RangeBounds` to +/// allow for comparison of items with range bounds. +pub trait ComparableRangeBounds: RangeBounds { + /// Returns `true` if `item` is contained in the range. + /// + /// # Examples + /// + /// See the [crate-level documentation](crate). + fn compare_contains(&self, item: &K) -> bool + where + Q: Comparable, + K: ?Sized, + { + (match self.start_bound() { + Bound::Included(start) => start.compare(item) != Ordering::Greater, + Bound::Excluded(start) => start.compare(item) == Ordering::Less, + Bound::Unbounded => true, + }) && (match self.end_bound() { + Bound::Included(end) => end.compare(item) != Ordering::Less, + Bound::Excluded(end) => end.compare(item) == Ordering::Greater, + Bound::Unbounded => true, + }) + } +} + +impl ComparableRangeBounds for R +where + R: ?Sized + RangeBounds, + T: ?Sized, +{ +} From 5e9686ff4124c85b8f37c56c4d8bae0885ebd50b Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 22 Jan 2025 09:55:37 -0800 Subject: [PATCH 2/4] ci: bump MSRV to 1.28 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 06260a0..e66265c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,7 @@ jobs: strategy: matrix: include: - - rust: 1.6.0 # MSRV + - rust: 1.28.0 # MSRV - rust: stable - rust: beta - rust: nightly From 9cde2a4654a9b0f5e17759140060e2c92f074de0 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 22 Jan 2025 10:03:52 -0800 Subject: [PATCH 3/4] Tweak the `ComparableRangeBounds` example and impl --- src/lib.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 19981ae..f756f91 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -57,9 +57,10 @@ //! assert_eq!(q2.compare(&key), Ordering::Less); //! assert_eq!(q3.compare(&key), Ordering::Greater); //! -//! // You cannot do this with the `RangeBounds::contains` method. -//! // assert!((q1..q3).contains(key)); -//! // But you can do this with the `ComparableRangeBounds::compare_contains` method. +//! // You cannot use `Comparable` with the `RangeBounds::contains` method: +//! // assert!((q1..q3).contains(&key)); +//! +//! // But you can use the `ComparableRangeBounds::compare_contains` method: //! assert!((q1..q3).compare_contains(&key)); //! } //! ``` @@ -143,9 +144,9 @@ pub trait ComparableRangeBounds: RangeBounds { } } -impl ComparableRangeBounds for R +impl ComparableRangeBounds for R where - R: ?Sized + RangeBounds, - T: ?Sized, + R: ?Sized + RangeBounds, + Q: ?Sized, { } From 9135d9c6a9b4f3fb5e5de9ce3f619202162e93f7 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 22 Jan 2025 10:04:19 -0800 Subject: [PATCH 4/4] Use consistent style for `Equivalent` and `Comparable` too --- src/lib.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index f756f91..0cd58ab 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -86,10 +86,10 @@ pub trait Equivalent { fn equivalent(&self, key: &K) -> bool; } -impl Equivalent for Q +impl Equivalent for Q where - Q: Eq, - K: Borrow, + Q: ?Sized + Eq, + K: ?Sized + Borrow, { #[inline] fn equivalent(&self, key: &K) -> bool { @@ -108,10 +108,10 @@ pub trait Comparable: Equivalent { fn compare(&self, key: &K) -> Ordering; } -impl Comparable for Q +impl Comparable for Q where - Q: Ord, - K: Borrow, + Q: ?Sized + Ord, + K: ?Sized + Borrow, { #[inline] fn compare(&self, key: &K) -> Ordering {