#![doc = include_str!("../README.md")]
#![no_std]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(docsrs, allow(unused_attributes))]
#![allow(rustdoc::bare_urls)]
#![deny(missing_docs)]
#[cfg(test)]
extern crate std;
use core::{borrow::Borrow, cmp::Ordering};
pub trait Equivalent<Q: ?Sized> {
fn equivalent(&self, key: &Q) -> bool;
}
impl<K: ?Sized, Q: ?Sized> Equivalent<Q> for K
where
K: Borrow<Q>,
Q: Eq,
{
#[inline]
fn equivalent(&self, key: &Q) -> bool {
PartialEq::eq(self.borrow(), key)
}
}
pub trait Comparable<Q: ?Sized>: Equivalent<Q> {
fn compare(&self, key: &Q) -> Ordering;
}
impl<K: ?Sized, Q: ?Sized> Comparable<Q> for K
where
K: Borrow<Q>,
Q: Ord,
{
#[inline]
fn compare(&self, key: &Q) -> Ordering {
Ord::cmp(self.borrow(), key)
}
}
pub trait ComparableRangeBounds<Q: ?Sized>: core::ops::RangeBounds<Q> {
fn compare_contains<K>(&self, item: &K) -> bool
where
K: ?Sized + Comparable<Q>,
{
use core::ops::Bound;
(match self.start_bound() {
Bound::Included(start) => item.compare(start) != Ordering::Less,
Bound::Excluded(start) => item.compare(start) == Ordering::Greater,
Bound::Unbounded => true,
}) && (match self.end_bound() {
Bound::Included(end) => item.compare(end) != Ordering::Greater,
Bound::Excluded(end) => item.compare(end) == Ordering::Less,
Bound::Unbounded => true,
})
}
}
impl<R, Q> ComparableRangeBounds<Q> for R
where
R: ?Sized + core::ops::RangeBounds<Q>,
Q: ?Sized,
{
}