ltrait_extra/
sorter.rs

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