moirai_iter/parallel/adapters/
filter.rs1use super::super::{Consumer, FilterConsumer, FilterMapConsumer, ParallelIterator, VecParIter};
2use super::map::Map;
3use super::pair::ZipEq;
4use std::ops::ControlFlow;
5
6pub struct Filter<I, F> {
8 pub(super) base: I,
9 pub(super) filter_fn: F,
10}
11
12impl<I, F> Filter<I, F> {
13 pub(crate) fn new(base: I, filter_fn: F) -> Self {
14 Self { base, filter_fn }
15 }
16}
17
18impl<I, J, MapFn, FilterFn, Mapped> Filter<Map<ZipEq<I, J>, MapFn>, FilterFn>
19where
20 I: ParallelIterator,
21 J: ParallelIterator,
22 I::Item: Sync + 'static,
23 J::Item: Sync + 'static,
24 MapFn: Fn((I::Item, J::Item)) -> Mapped + Send + Sync + Clone,
25 FilterFn: Fn(&Mapped) -> bool + Send + Sync + Clone,
26 Mapped: Send,
27{
28 pub fn collect<C>(self) -> C
30 where
31 C: FromIterator<Mapped> + Send,
32 {
33 let filter_fn = self.filter_fn;
34 let map = self.base;
35 let map_fn = map.map_fn;
36 let zip = map.base;
37 let left = zip.left.seq_items();
38 let right = zip.right.seq_items();
39 assert_eq!(
40 left.len(),
41 right.len(),
42 "zip_eq requires equal input lengths"
43 );
44
45 left.into_iter()
46 .zip(right)
47 .map(map_fn)
48 .filter(filter_fn)
49 .collect()
50 }
51}
52
53impl<I, F> ParallelIterator for Filter<I, F>
54where
55 I: ParallelIterator,
56 F: Fn(&I::Item) -> bool + Send + Sync + Clone,
57{
58 type Item = I::Item;
59
60 fn seq_items(self) -> Vec<Self::Item> {
61 self.base
62 .seq_items()
63 .into_iter()
64 .filter(|x| (self.filter_fn)(x))
65 .collect()
66 }
67
68 fn seq_iter(self) -> impl Iterator<Item = Self::Item> {
69 self.base.seq_iter().filter(self.filter_fn)
70 }
71
72 fn seq_try_fold<Acc, B, FoldFn>(self, init: Acc, mut fold_fn: FoldFn) -> ControlFlow<B, Acc>
73 where
74 FoldFn: FnMut(Acc, Self::Item) -> ControlFlow<B, Acc>,
75 {
76 let filter_fn = self.filter_fn;
77 self.base.seq_try_fold(init, move |accumulator, item| {
78 if filter_fn(&item) {
79 fold_fn(accumulator, item)
80 } else {
81 ControlFlow::Continue(accumulator)
82 }
83 })
84 }
85
86 fn drive<C, R>(self, consumer: C) -> R
87 where
88 C: Consumer<Self::Item, Result = R> + Send + Sync,
89 R: Send,
90 {
91 self.base
92 .drive(FilterConsumer::new(consumer, self.filter_fn))
93 }
94}
95
96pub struct FilterMap<I, F> {
98 pub(super) base: I,
99 pub(super) filter_map_fn: F,
100}
101
102impl<I, F> FilterMap<I, F> {
103 pub(crate) fn new(base: I, filter_map_fn: F) -> Self {
104 Self {
105 base,
106 filter_map_fn,
107 }
108 }
109}
110
111impl<I, F, R> ParallelIterator for FilterMap<I, F>
112where
113 I: ParallelIterator,
114 F: Fn(I::Item) -> Option<R> + Send + Sync + Clone,
115 R: Send + Sync + 'static,
116{
117 type Item = R;
118
119 fn seq_try_fold<Acc, B, FoldFn>(self, init: Acc, mut fold_fn: FoldFn) -> ControlFlow<B, Acc>
120 where
121 FoldFn: FnMut(Acc, Self::Item) -> ControlFlow<B, Acc>,
122 {
123 let filter_map_fn = self.filter_map_fn;
124 self.base
125 .seq_try_fold(init, move |accumulator, item| match filter_map_fn(item) {
126 Some(mapped) => fold_fn(accumulator, mapped),
127 None => ControlFlow::Continue(accumulator),
128 })
129 }
130
131 fn seq_items(self) -> Vec<Self::Item> {
132 self.base
133 .seq_items()
134 .into_iter()
135 .filter_map(self.filter_map_fn)
136 .collect()
137 }
138
139 fn drive<C, R2>(self, consumer: C) -> R2
140 where
141 C: Consumer<Self::Item, Result = R2> + Send + Sync,
142 R2: Send,
143 {
144 self.base
149 .drive(FilterMapConsumer::new(consumer, self.filter_map_fn))
150 }
151}
152
153pub struct WhileSome<I> {
155 pub(super) base: I,
156}
157
158impl<I> WhileSome<I> {
159 pub(crate) fn new(base: I) -> Self {
160 Self { base }
161 }
162}
163
164impl<I, T> ParallelIterator for WhileSome<I>
165where
166 I: ParallelIterator<Item = Option<T>>,
167 T: Send + Sync + 'static,
168{
169 type Item = T;
170
171 fn seq_items(self) -> Vec<Self::Item> {
172 self.base
173 .seq_items()
174 .into_iter()
175 .map_while(|item| item)
176 .collect()
177 }
178
179 fn drive<C, R>(self, consumer: C) -> R
189 where
190 C: Consumer<Self::Item, Result = R> + Send + Sync,
191 R: Send,
192 {
193 consumer.consume(VecParIter::new(self.seq_items()))
194 }
195}