no_order/lib.rs
1/// A helper struct for no ordering, where every instance of NoOrder<T> is equivalent to any other NoOrder<T>.
2///
3/// This struct is a helper to be used with data structures like [`std::collections::BinaryHeap`] or [`std::collections::HashSet`],
4/// and can be used to ignore ordering or hashing of part of a key.
5///
6/// Can be used for faster performance or when an key does not implement [`std::cmp::Ord`] or [`std::hash::Hash`],
7/// and is not relavant.
8///
9/// # Examples
10///
11/// ```
12/// use no_order::NoOrder;
13/// use std::collections::BinaryHeap;
14/// use std::collections::HashSet;
15///
16/// // Any NoOrder is equivalent to any other.
17/// assert_eq!(NoOrder(1), NoOrder(2));
18/// assert_eq!(NoOrder(1), NoOrder(1));
19///
20/// // This means that they also share the same key.
21/// let set = HashSet::from([NoOrder(1), NoOrder(1), NoOrder(2), NoOrder(3)]);
22/// assert_eq!(set.len(), 1);
23///
24/// // And can be used to ignore the the second value in a tuple.
25/// let set_tuple = HashSet::from([(1, NoOrder(1)), (2, NoOrder(1)), (2, NoOrder(2))]);
26/// assert_eq!(set_tuple.len(), 2);
27///
28/// // When used in a heap or tree like data structure, we can store extra data without sorting on it.
29/// // This means that we can use types that do not traditionally implement Ord.
30/// let mut heap = BinaryHeap::new();
31/// heap.push((2, NoOrder(1.24)));
32/// heap.push((1, NoOrder(2.15)));
33/// heap.push((2, NoOrder(3.74)));
34/// heap.push((2, NoOrder(2.96)));
35///
36/// // It only acts as a max heap on the first value,
37/// // and the ordering on the second value is undefiend.
38/// while let Some((a, NoOrder(b))) = heap.pop() {
39/// println!("{a}, {b}");
40/// }
41/// ```
42#[repr(transparent)]
43#[derive(Debug, Copy, Default)]
44pub struct NoOrder<T>(pub T);
45
46impl<T> PartialEq for NoOrder<T> {
47 fn eq(&self, _: &Self) -> bool {
48 true
49 }
50}
51
52impl<T> PartialOrd for NoOrder<T> {
53 fn partial_cmp(&self, _: &Self) -> Option<std::cmp::Ordering> {
54 Some(std::cmp::Ordering::Equal)
55 }
56}
57
58impl<T> Eq for NoOrder<T> {}
59
60impl<T> Ord for NoOrder<T> {
61 fn cmp(&self, _: &Self) -> std::cmp::Ordering {
62 std::cmp::Ordering::Equal
63 }
64}
65
66impl<T> std::hash::Hash for NoOrder<T> {
67 fn hash<H: std::hash::Hasher>(&self, _: &mut H) {}
68}
69
70impl<T: Clone> Clone for NoOrder<T> {
71 fn clone(&self) -> Self {
72 Self(self.0.clone())
73 }
74 fn clone_from(&mut self, source: &Self) {
75 self.0.clone_from(&source.0)
76 }
77}