1use super::{plumbing::*, *};
2
3#[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
76 fn callback<P>(self, base: P) -> CB::Output
77 where
78 P: Producer<Item = T>,
79 {
80 let producer = MinLenProducer {
81 base,
82 min: self.min,
83 };
84 self.callback.callback(producer)
85 }
86 }
87 }
88}
89
90struct MinLenProducer<P> {
94 base: P,
95 min: usize,
96}
97
98impl<P> Producer for MinLenProducer<P>
99where
100 P: Producer,
101{
102 type IntoIter = P::IntoIter;
103 type Item = P::Item;
104
105 fn into_iter(self) -> Self::IntoIter {
106 self.base.into_iter()
107 }
108
109 fn min_len(&self) -> usize {
110 Ord::max(self.min, self.base.min_len())
111 }
112
113 fn max_len(&self) -> usize {
114 self.base.max_len()
115 }
116
117 fn split_at(self, index: usize) -> (Self, Self) {
118 let (left, right) = self.base.split_at(index);
119 (
120 MinLenProducer {
121 base: left,
122 min: self.min,
123 },
124 MinLenProducer {
125 base: right,
126 min: self.min,
127 },
128 )
129 }
130
131 fn fold_with<F>(self, folder: F) -> F
132 where
133 F: Folder<Self::Item>,
134 {
135 self.base.fold_with(folder)
136 }
137}
138
139#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
146#[derive(Debug, Clone)]
147pub struct MaxLen<I: IndexedParallelIterator> {
148 base: I,
149 max: usize,
150}
151
152impl<I> MaxLen<I>
153where
154 I: IndexedParallelIterator,
155{
156 pub(super) fn new(base: I, max: usize) -> Self {
158 MaxLen { base, max }
159 }
160}
161
162impl<I> ParallelIterator for MaxLen<I>
163where
164 I: IndexedParallelIterator,
165{
166 type Item = I::Item;
167
168 fn drive_unindexed<C>(self, consumer: C) -> C::Result
169 where
170 C: UnindexedConsumer<Self::Item>,
171 {
172 bridge(self, consumer)
173 }
174
175 fn opt_len(&self) -> Option<usize> {
176 Some(self.len())
177 }
178}
179
180impl<I> IndexedParallelIterator for MaxLen<I>
181where
182 I: IndexedParallelIterator,
183{
184 fn drive<C: Consumer<Self::Item>>(self, consumer: C) -> C::Result {
185 bridge(self, consumer)
186 }
187
188 fn len(&self) -> usize {
189 self.base.len()
190 }
191
192 fn with_producer<CB>(self, callback: CB) -> CB::Output
193 where
194 CB: ProducerCallback<Self::Item>,
195 {
196 return self.base.with_producer(Callback {
197 callback,
198 max: self.max,
199 });
200
201 struct Callback<CB> {
202 callback: CB,
203 max: usize,
204 }
205
206 impl<T, CB> ProducerCallback<T> for Callback<CB>
207 where
208 CB: ProducerCallback<T>,
209 {
210 type Output = CB::Output;
211
212 fn callback<P>(self, base: P) -> CB::Output
213 where
214 P: Producer<Item = T>,
215 {
216 let producer = MaxLenProducer {
217 base,
218 max: self.max,
219 };
220 self.callback.callback(producer)
221 }
222 }
223 }
224}
225
226struct MaxLenProducer<P> {
230 base: P,
231 max: usize,
232}
233
234impl<P> Producer for MaxLenProducer<P>
235where
236 P: Producer,
237{
238 type IntoIter = P::IntoIter;
239 type Item = P::Item;
240
241 fn into_iter(self) -> Self::IntoIter {
242 self.base.into_iter()
243 }
244
245 fn min_len(&self) -> usize {
246 self.base.min_len()
247 }
248
249 fn max_len(&self) -> usize {
250 Ord::min(self.max, self.base.max_len())
251 }
252
253 fn split_at(self, index: usize) -> (Self, Self) {
254 let (left, right) = self.base.split_at(index);
255 (
256 MaxLenProducer {
257 base: left,
258 max: self.max,
259 },
260 MaxLenProducer {
261 base: right,
262 max: self.max,
263 },
264 )
265 }
266
267 fn fold_with<F>(self, folder: F) -> F
268 where
269 F: Folder<Self::Item>,
270 {
271 self.base.fold_with(folder)
272 }
273}