ltrait_extra/
filter.rs

1use ltrait::{filter::FilterWrapper, Filter};
2use std::marker::PhantomData;
3
4impl<'a, T> FilterExt<'a> for T where T: Filter<'a> {}
5
6pub trait FilterExt<'a>: Filter<'a> {
7    fn to_if<Cusion, F, TransF>(
8        self,
9        f: F,
10        transformer: TransF,
11    ) -> impl Filter<'a, Context = Cusion>
12    // Wrapもされる
13    where
14        Self: Sized,
15        Cusion: Sync + Send + 'a,
16        F: Fn(&Cusion) -> bool + Send + 'a,
17        TransF: Fn(&Cusion) -> <Self as Filter<'a>>::Context + Send + 'a,
18        <Self as Filter<'a>>::Context: Sync,
19    {
20        FilterIf::new(self, f, transformer)
21    }
22
23    fn reverse(self) -> impl Filter<'a, Context = <Self as Filter<'a>>::Context>
24    where
25        Self: Sized,
26        <Self as Filter<'a>>::Context: Sync,
27    {
28        ReversedFilter::new(self)
29    }
30
31    fn comb<Cusion, T, Ctx, F1, F2, F3>(
32        self,
33        transformer1: F1,
34        filter2: T,
35        transformer2: F2,
36        predicater: F3,
37    ) -> impl Filter<'a, Context = Cusion>
38    where
39        Self: Sized,
40
41        T: Filter<'a, Context = Ctx>,
42
43        F1: Fn(&Cusion) -> <Self as Filter<'a>>::Context + Send + 'a,
44        F2: Fn(&Cusion) -> Ctx + Send + 'a,
45        F3: Fn(bool, bool) -> bool + Send + 'a,
46
47        Cusion: Sync + 'a,
48        Ctx: 'a,
49    {
50        FilterComb::new(self, transformer1, filter2, transformer2, predicater)
51    }
52}
53
54pub struct FilterComb<'a, Cusion, T1, T2, C1, C2, F1, F2, F3>
55where
56    F1: Fn(&Cusion) -> C1 + Send + 'a,
57    F2: Fn(&Cusion) -> C2 + Send + 'a,
58    F3: Fn(bool, bool) -> bool + Send + 'a,
59
60    T1: Filter<'a, Context = C1>,
61    T2: Filter<'a, Context = C2>,
62
63    C1: 'a,
64    C2: 'a,
65
66    Cusion: Sync,
67{
68    filter1: T1,
69    filter2: T2,
70
71    transformer1: F1,
72    transformer2: F2,
73
74    predicater: F3,
75
76    _cusion: PhantomData<&'a Cusion>,
77}
78
79impl<'a, Cusion, T1, T2, C1, C2, F1, F2, F3> Filter<'a>
80    for FilterComb<'a, Cusion, T1, T2, C1, C2, F1, F2, F3>
81where
82    F1: Fn(&Cusion) -> C1 + Send + 'a,
83    F2: Fn(&Cusion) -> C2 + Send + 'a,
84    F3: Fn(bool, bool) -> bool + Send + 'a,
85
86    T1: Filter<'a, Context = C1>,
87    T2: Filter<'a, Context = C2>,
88
89    C1: 'a,
90    C2: 'a,
91
92    Cusion: Sync,
93{
94    type Context = Cusion;
95
96    fn predicate(&self, ctx: &Self::Context, input: &str) -> bool {
97        (self.predicater)(
98            self.filter1.predicate(&(self.transformer1)(ctx), input),
99            self.filter2.predicate(&(self.transformer2)(ctx), input),
100        )
101    }
102}
103
104impl<'a, Cusion, T1, T2, C1, C2, F1, F2, F3> FilterComb<'a, Cusion, T1, T2, C1, C2, F1, F2, F3>
105where
106    F1: Fn(&Cusion) -> C1 + Send + 'a,
107    F2: Fn(&Cusion) -> C2 + Send + 'a,
108    F3: Fn(bool, bool) -> bool + Send + 'a,
109
110    T1: Filter<'a, Context = C1>,
111    T2: Filter<'a, Context = C2>,
112
113    C1: 'a,
114    C2: 'a,
115
116    Cusion: Sync,
117{
118    pub fn new(
119        filter1: T1,
120        transformer1: F1,
121        filter2: T2,
122        transformer2: F2,
123        predicater: F3,
124    ) -> Self {
125        Self {
126            filter1,
127            filter2,
128            transformer1,
129            transformer2,
130            predicater,
131            _cusion: PhantomData,
132        }
133    }
134}
135
136pub struct FilterIf<'a, T, Ctx, F>
137where
138    T: Filter<'a, Context = Ctx>,
139    F: Fn(&Ctx) -> bool + Send + 'a,
140    Ctx: Sync,
141{
142    filter: T,
143
144    f: F,
145
146    _ctx: PhantomData<&'a Ctx>,
147}
148
149impl<'a, Cusion, F, InnerF, TransF, Ctx>
150    FilterIf<'a, FilterWrapper<'a, Ctx, InnerF, TransF, Cusion>, Cusion, F>
151where
152    F: Fn(&Cusion) -> bool + Send + 'a,
153    Cusion: Sync + Send,
154    TransF: Fn(&Cusion) -> Ctx + Send,
155    InnerF: Filter<'a, Context = Ctx>,
156    Ctx: Sync,
157{
158    pub fn new(filter: InnerF, f: F, transformer: TransF) -> Self {
159        Self {
160            filter: FilterWrapper::new(filter, transformer),
161            f,
162            _ctx: PhantomData,
163        }
164    }
165}
166
167impl<'a, T, Ctx, F> Filter<'a> for FilterIf<'a, T, Ctx, F>
168where
169    T: Filter<'a, Context = Ctx>,
170    F: Fn(&Ctx) -> bool + Send + 'a,
171    Ctx: Sync,
172{
173    type Context = Ctx;
174
175    fn predicate(&self, ctx: &Self::Context, input: &str) -> bool {
176        if (self.f)(ctx) {
177            self.filter.predicate(ctx, input)
178        } else {
179            true
180        }
181    }
182}
183
184pub struct ReversedFilter<'a, T, Ctx>
185where
186    T: Filter<'a, Context = Ctx>,
187    Ctx: Sync,
188{
189    filter: T,
190
191    _ctx: PhantomData<&'a Ctx>,
192}
193
194impl<'a, T, Ctx> ReversedFilter<'a, T, Ctx>
195where
196    T: Filter<'a, Context = Ctx>,
197    Ctx: Sync,
198{
199    pub fn new(filter: T) -> Self {
200        Self {
201            filter,
202            _ctx: PhantomData,
203        }
204    }
205}
206
207impl<'a, T, Ctx> Filter<'a> for ReversedFilter<'a, T, Ctx>
208where
209    T: Filter<'a, Context = Ctx>,
210    Ctx: Sync,
211{
212    type Context = Ctx;
213
214    fn predicate(&self, ctx: &Self::Context, input: &str) -> bool {
215        !self.filter.predicate(ctx, input)
216    }
217}