1use super::plumbing::*;
2use super::*;
3
4use std::fmt::{self, Debug};
5use std::iter;
6
7#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
13#[derive(Clone)]
14pub struct Map<I, F> {
15 base: I,
16 map_op: F,
17}
18
19impl<I: Debug, F> Debug for Map<I, F> {
20 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21 f.debug_struct("Map").field("base", &self.base).finish()
22 }
23}
24
25impl<I, F> Map<I, F> {
26 pub(super) fn new(base: I, map_op: F) -> Self {
28 Map { base, map_op }
29 }
30}
31
32impl<I, F, R> ParallelIterator for Map<I, F>
33where
34 I: ParallelIterator,
35 F: Fn(I::Item) -> R + Sync + Send,
36 R: Send,
37{
38 type Item = F::Output;
39
40 fn drive_unindexed<C>(self, consumer: C) -> C::Result
41 where
42 C: UnindexedConsumer<Self::Item>,
43 {
44 let consumer1 = MapConsumer::new(consumer, &self.map_op);
45 self.base.drive_unindexed(consumer1)
46 }
47
48 fn opt_len(&self) -> Option<usize> {
49 self.base.opt_len()
50 }
51}
52
53impl<I, F, R> IndexedParallelIterator for Map<I, F>
54where
55 I: IndexedParallelIterator,
56 F: Fn(I::Item) -> R + Sync + Send,
57 R: Send,
58{
59 fn drive<C>(self, consumer: C) -> C::Result
60 where
61 C: Consumer<Self::Item>,
62 {
63 let consumer1 = MapConsumer::new(consumer, &self.map_op);
64 self.base.drive(consumer1)
65 }
66
67 fn len(&self) -> usize {
68 self.base.len()
69 }
70
71 fn with_producer<CB>(self, callback: CB) -> CB::Output
72 where
73 CB: ProducerCallback<Self::Item>,
74 {
75 return self.base.with_producer(Callback {
76 callback,
77 map_op: self.map_op,
78 });
79
80 struct Callback<CB, F> {
81 callback: CB,
82 map_op: F,
83 }
84
85 impl<T, F, R, CB> ProducerCallback<T> for Callback<CB, F>
86 where
87 CB: ProducerCallback<R>,
88 F: Fn(T) -> R + Sync,
89 R: Send,
90 {
91 type Output = CB::Output;
92
93 fn callback<P>(self, base: P) -> CB::Output
94 where
95 P: Producer<Item = T>,
96 {
97 let producer = MapProducer {
98 base,
99 map_op: &self.map_op,
100 };
101 self.callback.callback(producer)
102 }
103 }
104 }
105}
106
107struct MapProducer<'f, P, F> {
110 base: P,
111 map_op: &'f F,
112}
113
114impl<'f, P, F, R> Producer for MapProducer<'f, P, F>
115where
116 P: Producer,
117 F: Fn(P::Item) -> R + Sync,
118 R: Send,
119{
120 type Item = F::Output;
121 type IntoIter = iter::Map<P::IntoIter, &'f F>;
122
123 fn into_iter(self) -> Self::IntoIter {
124 self.base.into_iter().map(self.map_op)
125 }
126
127 fn min_len(&self) -> usize {
128 self.base.min_len()
129 }
130 fn max_len(&self) -> usize {
131 self.base.max_len()
132 }
133
134 fn split_at(self, index: usize) -> (Self, Self) {
135 let (left, right) = self.base.split_at(index);
136 (
137 MapProducer {
138 base: left,
139 map_op: self.map_op,
140 },
141 MapProducer {
142 base: right,
143 map_op: self.map_op,
144 },
145 )
146 }
147
148 fn fold_with<G>(self, folder: G) -> G
149 where
150 G: Folder<Self::Item>,
151 {
152 let folder1 = MapFolder {
153 base: folder,
154 map_op: self.map_op,
155 };
156 self.base.fold_with(folder1).base
157 }
158}
159
160struct MapConsumer<'f, C, F> {
164 base: C,
165 map_op: &'f F,
166}
167
168impl<'f, C, F> MapConsumer<'f, C, F> {
169 fn new(base: C, map_op: &'f F) -> Self {
170 MapConsumer { base, map_op }
171 }
172}
173
174impl<'f, T, R, C, F> Consumer<T> for MapConsumer<'f, C, F>
175where
176 C: Consumer<F::Output>,
177 F: Fn(T) -> R + Sync,
178 R: Send,
179{
180 type Folder = MapFolder<'f, C::Folder, F>;
181 type Reducer = C::Reducer;
182 type Result = C::Result;
183
184 fn split_at(self, index: usize) -> (Self, Self, Self::Reducer) {
185 let (left, right, reducer) = self.base.split_at(index);
186 (
187 MapConsumer::new(left, self.map_op),
188 MapConsumer::new(right, self.map_op),
189 reducer,
190 )
191 }
192
193 fn into_folder(self) -> Self::Folder {
194 MapFolder {
195 base: self.base.into_folder(),
196 map_op: self.map_op,
197 }
198 }
199
200 fn full(&self) -> bool {
201 self.base.full()
202 }
203}
204
205impl<'f, T, R, C, F> UnindexedConsumer<T> for MapConsumer<'f, C, F>
206where
207 C: UnindexedConsumer<F::Output>,
208 F: Fn(T) -> R + Sync,
209 R: Send,
210{
211 fn split_off_left(&self) -> Self {
212 MapConsumer::new(self.base.split_off_left(), self.map_op)
213 }
214
215 fn to_reducer(&self) -> Self::Reducer {
216 self.base.to_reducer()
217 }
218}
219
220struct MapFolder<'f, C, F> {
221 base: C,
222 map_op: &'f F,
223}
224
225impl<'f, T, R, C, F> Folder<T> for MapFolder<'f, C, F>
226where
227 C: Folder<F::Output>,
228 F: Fn(T) -> R,
229{
230 type Result = C::Result;
231
232 fn consume(self, item: T) -> Self {
233 let mapped_item = (self.map_op)(item);
234 MapFolder {
235 base: self.base.consume(mapped_item),
236 map_op: self.map_op,
237 }
238 }
239
240 fn consume_iter<I>(mut self, iter: I) -> Self
241 where
242 I: IntoIterator<Item = T>,
243 {
244 self.base = self.base.consume_iter(iter.into_iter().map(self.map_op));
245 self
246 }
247
248 fn complete(self) -> C::Result {
249 self.base.complete()
250 }
251
252 fn full(&self) -> bool {
253 self.base.full()
254 }
255}