Coverage Report

Created: 2026-10-28 07:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/equivalent-1.0.3/src/lib.rs
Line
Count
Source
1
//! [`Equivalent`] and [`Comparable`] are traits for key comparison in maps.
2
//!
3
//! These may be used in the implementation of maps where the lookup type `Q`
4
//! may be different than the stored key type `K`.
5
//!
6
//! * `Q: Equivalent<K>` checks for equality, similar to the `HashMap<K, V>`
7
//!   constraint `K: Borrow<Q>, Q: Eq`.
8
//! * `Q: Comparable<K>` checks the ordering, similar to the `BTreeMap<K, V>`
9
//!   constraint `K: Borrow<Q>, Q: Ord`.
10
//!
11
//! These traits are not used by the maps in the standard library, but they may
12
//! add more flexibility in third-party map implementations, especially in
13
//! situations where a strict `K: Borrow<Q>` relationship is not available.
14
//!
15
//! # Examples
16
//!
17
//! ```
18
//! use equivalent::*;
19
//! use std::cmp::Ordering;
20
//!
21
//! pub struct Pair<A, B>(pub A, pub B);
22
//!
23
//! impl<'a, A: ?Sized, B: ?Sized, C, D> Equivalent<(C, D)> for Pair<&'a A, &'a B>
24
//! where
25
//!     A: Equivalent<C>,
26
//!     B: Equivalent<D>,
27
//! {
28
//!     fn equivalent(&self, key: &(C, D)) -> bool {
29
//!         self.0.equivalent(&key.0) && self.1.equivalent(&key.1)
30
//!     }
31
//! }
32
//!
33
//! impl<'a, A: ?Sized, B: ?Sized, C, D> Comparable<(C, D)> for Pair<&'a A, &'a B>
34
//! where
35
//!     A: Comparable<C>,
36
//!     B: Comparable<D>,
37
//! {
38
//!     fn compare(&self, key: &(C, D)) -> Ordering {
39
//!         match self.0.compare(&key.0) {
40
//!             Ordering::Equal => self.1.compare(&key.1),
41
//!             not_equal => not_equal,
42
//!         }
43
//!     }
44
//! }
45
//!
46
//! fn main() {
47
//!     let key = (String::from("foo"), String::from("bar"));
48
//!     let q1 = Pair("foo", "bar");
49
//!     let q2 = Pair("boo", "bar");
50
//!     let q3 = Pair("foo", "baz");
51
//!
52
//!     assert!(q1.equivalent(&key));
53
//!     assert!(!q2.equivalent(&key));
54
//!     assert!(!q3.equivalent(&key));
55
//!
56
//!     assert_eq!(q1.compare(&key), Ordering::Equal);
57
//!     assert_eq!(q2.compare(&key), Ordering::Less);
58
//!     assert_eq!(q3.compare(&key), Ordering::Greater);
59
//! }
60
//! ```
61
62
#![no_std]
63
64
use core::borrow::Borrow;
65
use core::cmp::Ordering;
66
67
/// Key equivalence trait.
68
///
69
/// This trait allows hash table lookup to be customized. It has one blanket
70
/// implementation that uses the regular solution with `Borrow` and `Eq`, just
71
/// like `HashMap` does, so that you can pass `&str` to lookup into a map with
72
/// `String` keys and so on.
73
///
74
/// # Contract
75
///
76
/// The implementor **must** hash like `K`, if it is hashable. In other words,
77
/// `self.equivalent(key)` implies `hash(self) == hash(key)`.
78
pub trait Equivalent<K: ?Sized> {
79
    /// Compare self to `key` and return `true` if they are equal.
80
    fn equivalent(&self, key: &K) -> bool;
81
}
82
83
impl<Q: ?Sized, K: ?Sized> Equivalent<K> for Q
84
where
85
    Q: Eq,
86
    K: Borrow<Q>,
87
{
88
    #[inline]
89
0
    fn equivalent(&self, key: &K) -> bool {
90
0
        PartialEq::eq(self, key.borrow())
91
0
    }
92
}
93
94
/// Key ordering trait.
95
///
96
/// This trait allows ordered map lookup to be customized. It has one blanket
97
/// implementation that uses the regular solution with `Borrow` and `Ord`, just
98
/// like `BTreeMap` does, so that you can pass `&str` to lookup into a map with
99
/// `String` keys and so on.
100
///
101
/// # Contract
102
///
103
/// Implementations **must** agree with [`Equivalent`], such that
104
/// `self.compare(key).is_eq()` always matches `self.equivalent(key)`.
105
pub trait Comparable<K: ?Sized>: Equivalent<K> {
106
    /// Compare self to `key` and return their ordering.
107
    fn compare(&self, key: &K) -> Ordering;
108
}
109
110
impl<Q: ?Sized, K: ?Sized> Comparable<K> for Q
111
where
112
    Q: Ord,
113
    K: Borrow<Q>,
114
{
115
    #[inline]
116
    fn compare(&self, key: &K) -> Ordering {
117
        Ord::cmp(self, key.borrow())
118
    }
119
}