1use ltrait::{Sorter, sorter::SorterWrapper};
2use std::marker::PhantomData;
3
4impl<T> SorterExt for T where T: Sorter {}
5
6pub trait SorterExt: Sorter {
7 fn to_if<Cushion, F, TransF>(self, f: F, transformer: TransF) -> impl Sorter<Context = Cushion>
8 where
10 Self: Sized,
11 Cushion: Sync + Send,
12 F: Fn(&Cushion) -> bool + Send,
13 TransF: Fn(&Cushion) -> <Self as Sorter>::Context + Send,
14 <Self as Sorter>::Context: Sync + Send,
15 {
16 SorterIf::new(self, f, transformer)
17 }
18
19 fn reverse(self) -> impl Sorter<Context = <Self as Sorter>::Context>
20 where
21 Self: Sized,
22 <Self as Sorter>::Context: Sync + Send,
23 {
24 ReversedSorter::new(self)
25 }
26}
27
28pub struct SorterIf<T, Cushion, F>
29where
30 T: Sorter<Context = Cushion>,
31 F: Fn(&Cushion) -> bool + Send,
32 Cushion: Sync,
33{
34 sorter: T,
35
36 f: F,
37
38 _ctx: PhantomData<Cushion>,
39}
40
41impl<Cushion, F, InnerT, TransF, Ctx>
42 SorterIf<SorterWrapper<Ctx, InnerT, TransF, Cushion>, Cushion, F>
43where
44 F: Fn(&Cushion) -> bool + Send,
45 Cushion: Sync + Send,
46 InnerT: Sorter<Context = Ctx>,
47 TransF: Fn(&Cushion) -> Ctx + Send,
48 Ctx: Sync + Send,
49{
50 pub fn new(sorter: InnerT, f: F, transformer: TransF) -> Self {
51 Self {
52 sorter: SorterWrapper::new(sorter, transformer),
53 f,
54 _ctx: PhantomData,
55 }
56 }
57}
58
59impl<T, Ctx, F> Sorter for SorterIf<T, Ctx, F>
60where
61 T: Sorter<Context = Ctx>,
62 F: Fn(&Ctx) -> bool + Send,
63 Ctx: Sync + Send,
64{
65 type Context = Ctx;
66
67 fn compare(&self, lhs: &Self::Context, rhs: &Self::Context, input: &str) -> std::cmp::Ordering {
68 if (self.f)(lhs) {
69 self.sorter.compare(lhs, rhs, input)
70 } else {
71 std::cmp::Ordering::Equal
72 }
73 }
74}
75
76pub struct ReversedSorter<T, Ctx>
77where
78 T: Sorter<Context = Ctx>,
79 Ctx: Sync,
80{
81 sorter: T,
82
83 _ctx: PhantomData<Ctx>,
84}
85
86impl<T, Ctx> ReversedSorter<T, Ctx>
87where
88 T: Sorter<Context = Ctx>,
89 Ctx: Sync,
90{
91 pub fn new(sorter: T) -> Self {
92 Self {
93 sorter,
94 _ctx: PhantomData,
95 }
96 }
97}
98
99impl<T, Ctx> Sorter for ReversedSorter<T, Ctx>
100where
101 T: Sorter<Context = Ctx>,
102 Ctx: Sync + Send,
103{
104 type Context = Ctx;
105
106 fn compare(&self, lhs: &Self::Context, rhs: &Self::Context, input: &str) -> std::cmp::Ordering {
107 self.sorter.compare(lhs, rhs, input).reverse()
108 }
109}