ltrait_extra/
filter.rs

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