1use super::plumbing::*;
2use super::*;
3
4#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
10#[derive(Debug, Clone)]
11pub struct MinLen<I: IndexedParallelIterator> {
12 base: I,
13 min: usize,
14}
15
16impl<I> MinLen<I>
17where
18 I: IndexedParallelIterator,
19{
20 pub(super) fn new(base: I, min: usize) -> Self {
22 MinLen { base, min }
23 }
24}
25
26impl<I> ParallelIterator for MinLen<I>
27where
28 I: IndexedParallelIterator,
29{
30 type Item = I::Item;
31
32 fn drive_unindexed<C>(self, consumer: C) -> C::Result
33 where
34 C: UnindexedConsumer<Self::Item>,
35 {
36 bridge(self, consumer)
37 }
38
39 fn opt_len(&self) -> Option<usize> {
40 Some(self.len())
41 }
42}
43
44impl<I> IndexedParallelIterator for MinLen<I>
45where
46 I: IndexedParallelIterator,
47{
48 fn drive<C: Consumer<Self::Item>>(self, consumer: C) -> C::Result {
49 bridge(self, consumer)
50 }
51
52 fn len(&self) -> usize {
53 self.base.len()
54 }
55
56 fn with_producer<CB>(self, callback: CB) -> CB::Output
57 where
58 CB: ProducerCallback<Self::Item>,
59 {
60 return self.base.with_producer(Callback {
61 callback,
62 min: self.min,
63 });
64
65 struct Callback<CB> {
66 callback: CB,
67 min: usize,
68 }
69
70 impl<T, CB> ProducerCallback<T> for Callback<CB>
71 where
72 CB: ProducerCallback<T>,
73 {
74 type Output = CB::Output;
75 fn callback<P>(self, base: P) -> CB::Output
76 where
77 P: Producer<Item = T>,
78 {
79 let producer = MinLenProducer {
80 base,
81 min: self.min,
82 };
83 self.callback.callback(producer)
84 }
85 }
86 }
87}
88
89struct MinLenProducer<P> {
93 base: P,
94 min: usize,
95}
96
97impl<P> Producer for MinLenProducer<P>
98where
99 P: Producer,
100{
101 type Item = P::Item;
102 type IntoIter = P::IntoIter;
103
104 fn into_iter(self) -> Self::IntoIter {
105 self.base.into_iter()
106 }
107
108 fn min_len(&self) -> usize {
109 Ord::max(self.min, self.base.min_len())
110 }
111
112 fn max_len(&self) -> usize {
113 self.base.max_len()
114 }
115
116 fn split_at(self, index: usize) -> (Self, Self) {
117 let (left, right) = self.base.split_at(index);
118 (
119 MinLenProducer {
120 base: left,
121 min: self.min,
122 },
123 MinLenProducer {
124 base: right,
125 min: self.min,
126 },
127 )
128 }
129
130 fn fold_with<F>(self, folder: F) -> F
131 where
132 F: Folder<Self::Item>,
133 {
134 self.base.fold_with(folder)
135 }
136}
137
138#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
144#[derive(Debug, Clone)]
145pub struct MaxLen<I: IndexedParallelIterator> {
146 base: I,
147 max: usize,
148}
149
150impl<I> MaxLen<I>
151where
152 I: IndexedParallelIterator,
153{
154 pub(super) fn new(base: I, max: usize) -> Self {
156 MaxLen { base, max }
157 }
158}
159
160impl<I> ParallelIterator for MaxLen<I>
161where
162 I: IndexedParallelIterator,
163{
164 type Item = I::Item;
165
166 fn drive_unindexed<C>(self, consumer: C) -> C::Result
167 where
168 C: UnindexedConsumer<Self::Item>,
169 {
170 bridge(self, consumer)
171 }
172
173 fn opt_len(&self) -> Option<usize> {
174 Some(self.len())
175 }
176}
177
178impl<I> IndexedParallelIterator for MaxLen<I>
179where
180 I: IndexedParallelIterator,
181{
182 fn drive<C: Consumer<Self::Item>>(self, consumer: C) -> C::Result {
183 bridge(self, consumer)
184 }
185
186 fn len(&self) -> usize {
187 self.base.len()
188 }
189
190 fn with_producer<CB>(self, callback: CB) -> CB::Output
191 where
192 CB: ProducerCallback<Self::Item>,
193 {
194 return self.base.with_producer(Callback {
195 callback,
196 max: self.max,
197 });
198
199 struct Callback<CB> {
200 callback: CB,
201 max: usize,
202 }
203
204 impl<T, CB> ProducerCallback<T> for Callback<CB>
205 where
206 CB: ProducerCallback<T>,
207 {
208 type Output = CB::Output;
209 fn callback<P>(self, base: P) -> CB::Output
210 where
211 P: Producer<Item = T>,
212 {
213 let producer = MaxLenProducer {
214 base,
215 max: self.max,
216 };
217 self.callback.callback(producer)
218 }
219 }
220 }
221}
222
223struct MaxLenProducer<P> {
227 base: P,
228 max: usize,
229}
230
231impl<P> Producer for MaxLenProducer<P>
232where
233 P: Producer,
234{
235 type Item = P::Item;
236 type IntoIter = P::IntoIter;
237
238 fn into_iter(self) -> Self::IntoIter {
239 self.base.into_iter()
240 }
241
242 fn min_len(&self) -> usize {
243 self.base.min_len()
244 }
245
246 fn max_len(&self) -> usize {
247 Ord::min(self.max, self.base.max_len())
248 }
249
250 fn split_at(self, index: usize) -> (Self, Self) {
251 let (left, right) = self.base.split_at(index);
252 (
253 MaxLenProducer {
254 base: left,
255 max: self.max,
256 },
257 MaxLenProducer {
258 base: right,
259 max: self.max,
260 },
261 )
262 }
263
264 fn fold_with<F>(self, folder: F) -> F
265 where
266 F: Folder<Self::Item>,
267 {
268 self.base.fold_with(folder)
269 }
270}