ltrait_extra/
sorter.rs

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    // Wrapもされる
9    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}