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