equivalent_flipped/
lib.rs1#![doc = include_str!("../README.md")]
5#![no_std]
6#![cfg_attr(docsrs, feature(doc_cfg))]
7#![cfg_attr(docsrs, allow(unused_attributes))]
8#![allow(rustdoc::bare_urls)]
9#![deny(missing_docs)]
10
11#[cfg(test)]
12extern crate std;
13
14use core::{borrow::Borrow, cmp::Ordering};
15
16pub trait Equivalent<Q: ?Sized> {
27 fn equivalent(&self, key: &Q) -> bool;
29}
30
31impl<K: ?Sized, Q: ?Sized> Equivalent<Q> for K
32where
33 K: Borrow<Q>,
34 Q: Eq,
35{
36 #[inline]
37 fn equivalent(&self, key: &Q) -> bool {
38 PartialEq::eq(self.borrow(), key)
39 }
40}
41
42pub trait Comparable<Q: ?Sized>: Equivalent<Q> {
49 fn compare(&self, key: &Q) -> Ordering;
51}
52
53impl<K: ?Sized, Q: ?Sized> Comparable<Q> for K
54where
55 K: Borrow<Q>,
56 Q: Ord,
57{
58 #[inline]
59 fn compare(&self, key: &Q) -> Ordering {
60 Ord::cmp(self.borrow(), key)
61 }
62}
63
64pub trait ComparableRangeBounds<Q: ?Sized>: core::ops::RangeBounds<Q> {
67 fn compare_contains<K>(&self, item: &K) -> bool
69 where
70 K: ?Sized + Comparable<Q>,
71 {
72 use core::ops::Bound;
73
74 (match self.start_bound() {
75 Bound::Included(start) => item.compare(start) != Ordering::Less,
76 Bound::Excluded(start) => item.compare(start) == Ordering::Greater,
77 Bound::Unbounded => true,
78 }) && (match self.end_bound() {
79 Bound::Included(end) => item.compare(end) != Ordering::Greater,
80 Bound::Excluded(end) => item.compare(end) == Ordering::Less,
81 Bound::Unbounded => true,
82 })
83 }
84}
85
86impl<R, Q> ComparableRangeBounds<Q> for R
87where
88 R: ?Sized + core::ops::RangeBounds<Q>,
89 Q: ?Sized,
90{
91}