extsort_iter/orderer/
mod.rs

1use std::cmp::Ordering;
2
3/// A generialisation of the Ord trait.
4/// The main difference is that the Orderer is able to
5/// reference some internal state as it is passed by ref
6/// and compares some other type.
7pub trait Orderer<T> {
8    /// the type to compare
9    fn compare(&self, left: &T, right: &T) -> Ordering;
10}
11
12/// An orderer that just delegates to the Ord implementation on the type itself
13#[derive(Default)]
14pub struct OrdOrderer {}
15impl OrdOrderer {
16    pub fn new() -> Self {
17        Default::default()
18    }
19}
20
21impl<T: Ord> Orderer<T> for OrdOrderer {
22    fn compare(&self, left: &T, right: &T) -> Ordering {
23        left.cmp(right)
24    }
25}
26
27/// an orderer that compares values based on a key extracted from then.
28pub struct KeyOrderer<F> {
29    key_extractor: F,
30}
31impl<F> KeyOrderer<F> {
32    pub fn new<T, K>(key_extractor: F) -> Self
33    where
34        F: Fn(&T) -> K,
35        K: Ord,
36    {
37        Self { key_extractor }
38    }
39}
40
41impl<F, T, K> Orderer<T> for KeyOrderer<F>
42where
43    F: Fn(&T) -> K,
44    K: Ord,
45{
46    fn compare(&self, left: &T, right: &T) -> Ordering {
47        let left = (self.key_extractor)(left);
48        let right = (self.key_extractor)(right);
49        left.cmp(&right)
50    }
51}
52
53/// an orderer that compares values by delegating to a comparison function
54pub struct FuncOrderer<F> {
55    comparator: F,
56}
57
58impl<F> FuncOrderer<F> {
59    pub fn new<T>(comparator: F) -> Self
60    where
61        F: Fn(&T, &T) -> Ordering,
62    {
63        Self { comparator }
64    }
65}
66
67impl<F, T> Orderer<T> for FuncOrderer<F>
68where
69    F: Fn(&T, &T) -> Ordering,
70{
71    fn compare(&self, left: &T, right: &T) -> Ordering {
72        (self.comparator)(left, right)
73    }
74}