1use std::cmp::Ordering;
23/// `MinScored<K, T>` holds a score `K` and a scored object `T` in
4/// a pair for use with a `BinaryHeap`.
5///
6/// `MinScored` compares in reverse order by the score, so that we can
7/// use `BinaryHeap` as a min-heap to extract the score-value pair with the
8/// least score.
9///
10/// **Note:** `MinScored` implements a total order (`Ord`), so that it is
11/// possible to use float types as scores.
12#[derive(Copy, Clone, Debug)]
13pub struct MinScored<K, T>(pub K, pub T);
1415impl<K: PartialOrd, T> PartialEq for MinScored<K, T> {
16#[inline]
17fn eq(&self, other: &MinScored<K, T>) -> bool {
18self.cmp(other) == Ordering::Equal
19 }
20}
2122impl<K: PartialOrd, T> Eq for MinScored<K, T> {}
2324impl<K: PartialOrd, T> PartialOrd for MinScored<K, T> {
25#[inline]
26fn partial_cmp(&self, other: &MinScored<K, T>) -> Option<Ordering> {
27Some(self.cmp(other))
28 }
29}
3031impl<K: PartialOrd, T> Ord for MinScored<K, T> {
32#[inline]
33fn cmp(&self, other: &MinScored<K, T>) -> Ordering {
34let a = &self.0;
35let b = &other.0;
36if a == b {
37 Ordering::Equal
38 } else if a < b {
39 Ordering::Greater
40 } else if a > b {
41 Ordering::Less
42 } else if a.ne(a) && b.ne(b) {
43// these are the NaN cases
44Ordering::Equal
45 } else if a.ne(a) {
46// Order NaN less, so that it is last in the MinScore order
47Ordering::Less
48 } else {
49 Ordering::Greater
50 }
51 }
52}
5354#[derive(Copy, Clone, Debug)]
55pub struct MaxScored<K, T>(pub K, pub T);
5657impl<K: PartialOrd, T> PartialEq for MaxScored<K, T> {
58#[inline]
59fn eq(&self, other: &MaxScored<K, T>) -> bool {
60self.cmp(other) == Ordering::Equal
61 }
62}
6364impl<K: PartialOrd, T> Eq for MaxScored<K, T> {}
6566impl<K: PartialOrd, T> PartialOrd for MaxScored<K, T> {
67#[inline]
68fn partial_cmp(&self, other: &MaxScored<K, T>) -> Option<Ordering> {
69Some(self.cmp(other))
70 }
71}
7273impl<K: PartialOrd, T> Ord for MaxScored<K, T> {
74#[inline]
75fn cmp(&self, other: &MaxScored<K, T>) -> Ordering {
76let a = &self.0;
77let b = &other.0;
78if a == b {
79 Ordering::Equal
80 } else if a < b {
81 Ordering::Less
82 } else if a > b {
83 Ordering::Greater
84 } else if a.ne(a) && b.ne(b) {
85// these are the NaN cases
86Ordering::Equal
87 } else if a.ne(a) {
88 Ordering::Less
89 } else {
90 Ordering::Greater
91 }
92 }
93}