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 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}