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