1
#![doc = include_str!("../README.md")]
2
#![no_std]
3
#![forbid(unsafe_code)]
4
#![warn(missing_docs, clippy::pedantic)]
5

            
6
use alloc::string::String;
7
use alloc::vec::Vec;
8
use core::cmp::Ordering;
9

            
10
#[cfg(test)]
11
extern crate std;
12

            
13
extern crate alloc;
14

            
15
/// Types supporting the [`Map<Key, Value>`] collection type.
16
pub mod map;
17
/// Types supporting the [`Set<T>`] collection type.
18
pub mod set;
19

            
20
pub use map::Map;
21
pub use set::Set;
22

            
23
#[cfg(feature = "serde")]
24
mod serde;
25

            
26
#[cfg(test)]
27
mod tests;
28

            
29
/// Provides a comparison between `Self` and `Other`.
30
///
31
/// This function should only be implemented for types who guarantee that their
32
/// `PartialOrd<Other>` implementations are identical to their `PartialOrd`
33
/// implementations. For example, `Path` and `PathBuf` can be interchangeably
34
/// compared regardless of whether the left or right or both are a `Path` or
35
/// `PathBuf`.
36
///
37
/// Why not just use `PartialOrd<Other>`? Unfortunately, `PartialOrd<str>` is
38
/// [not implemented for
39
/// `String`](https://github.com/rust-lang/rust/issues/82990). This led to
40
/// issues implementing the [`Map::entry`] function when passing a `&str`
41
/// when the `Key` type was `String`.
42
///
43
/// This trait is automatically implemented for types that implement `Ord` and
44
/// `PartialOrd<Other>`, but it additionally provides implementations for
45
/// `String`/`str` and `Vec<T>`/`[T]`.
46
///
47
/// **In general, this trait should not need to be implemented.** Implement
48
/// `Ord` on your `Key` type, and if needed, implement `PartialOrd<Other>` for
49
/// your borrowed form.
50
pub trait Sort<Other = Self>
51
where
52
    Other: ?Sized,
53
{
54
    /// Compare `self` and `other`, returning the comparison result.
55
    ///
56
    /// This function should be implemented identically to
57
    /// `Ord::cmp`/`PartialOrd::partial_cmp`.
58
    fn compare(&self, other: &Other) -> Ordering;
59
}
60

            
61
impl Sort<str> for String {
62
    #[inline]
63
6
    fn compare(&self, b: &str) -> Ordering {
64
6
        self.as_str().cmp(b)
65
6
    }
66
}
67

            
68
impl<T> Sort<[T]> for Vec<T>
69
where
70
    T: Ord,
71
{
72
    #[inline]
73
1
    fn compare(&self, b: &[T]) -> Ordering {
74
1
        self.as_slice().cmp(b)
75
1
    }
76
}
77

            
78
impl<Key, SearchFor> Sort<SearchFor> for Key
79
where
80
    Key: Ord + PartialOrd<SearchFor>,
81
{
82
    #[inline]
83
177102
    fn compare(&self, b: &SearchFor) -> Ordering {
84
177102
        self.partial_cmp(b).expect("comparison failed")
85
177102
    }
86
}