1 use super::plumbing
::*;
4 use std
::fmt
::{self, Debug}
;
8 /// `Inspect` is an iterator that calls a function with a reference to each
9 /// element before yielding it.
11 /// This struct is created by the [`inspect()`] method on [`ParallelIterator`]
13 /// [`inspect()`]: trait.ParallelIterator.html#method.inspect
14 /// [`ParallelIterator`]: trait.ParallelIterator.html
15 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
17 pub struct Inspect
<I
: ParallelIterator
, F
> {
22 impl<I
: ParallelIterator
+ Debug
, F
> Debug
for Inspect
<I
, F
> {
23 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
24 f
.debug_struct("Inspect")
25 .field("base", &self.base
)
30 /// Create a new `Inspect` iterator.
32 /// NB: a free fn because it is NOT part of the end-user API.
33 pub fn new
<I
, F
>(base
: I
, inspect_op
: F
) -> Inspect
<I
, F
>
34 where I
: ParallelIterator
38 inspect_op
: inspect_op
,
42 impl<I
, F
> ParallelIterator
for Inspect
<I
, F
>
43 where I
: ParallelIterator
,
44 F
: Fn(&I
::Item
) + Sync
+ Send
48 fn drive_unindexed
<C
>(self, consumer
: C
) -> C
::Result
49 where C
: UnindexedConsumer
<Self::Item
>
51 let consumer1
= InspectConsumer
::new(consumer
, &self.inspect_op
);
52 self.base
.drive_unindexed(consumer1
)
55 fn opt_len(&self) -> Option
<usize> {
60 impl<I
, F
> IndexedParallelIterator
for Inspect
<I
, F
>
61 where I
: IndexedParallelIterator
,
62 F
: Fn(&I
::Item
) + Sync
+ Send
64 fn drive
<C
>(self, consumer
: C
) -> C
::Result
65 where C
: Consumer
<Self::Item
>
67 let consumer1
= InspectConsumer
::new(consumer
, &self.inspect_op
);
68 self.base
.drive(consumer1
)
71 fn len(&self) -> usize {
75 fn with_producer
<CB
>(self, callback
: CB
) -> CB
::Output
76 where CB
: ProducerCallback
<Self::Item
>
79 .with_producer(Callback
{
81 inspect_op
: self.inspect_op
,
84 struct Callback
<CB
, F
> {
89 impl<T
, F
, CB
> ProducerCallback
<T
> for Callback
<CB
, F
>
90 where CB
: ProducerCallback
<T
>,
93 type Output
= CB
::Output
;
95 fn callback
<P
>(self, base
: P
) -> CB
::Output
96 where P
: Producer
<Item
= T
>
98 let producer
= InspectProducer
{
100 inspect_op
: &self.inspect_op
,
102 self.callback
.callback(producer
)
108 /// ////////////////////////////////////////////////////////////////////////
110 struct InspectProducer
<'f
, P
, F
: 'f
> {
115 impl<'f
, P
, F
> Producer
for InspectProducer
<'f
, P
, F
>
117 F
: Fn(&P
::Item
) + Sync
120 type IntoIter
= iter
::Inspect
<P
::IntoIter
, &'f F
>;
122 fn into_iter(self) -> Self::IntoIter
{
123 self.base
.into_iter().inspect(self.inspect_op
)
126 fn min_len(&self) -> usize {
130 fn max_len(&self) -> usize {
134 fn split_at(self, index
: usize) -> (Self, Self) {
135 let (left
, right
) = self.base
.split_at(index
);
138 inspect_op
: self.inspect_op
,
142 inspect_op
: self.inspect_op
,
146 fn fold_with
<G
>(self, folder
: G
) -> G
147 where G
: Folder
<Self::Item
>
149 let folder1
= InspectFolder { base: folder, inspect_op: self.inspect_op }
;
150 self.base
.fold_with(folder1
).base
155 /// ////////////////////////////////////////////////////////////////////////
156 /// Consumer implementation
158 struct InspectConsumer
<'f
, C
, F
: 'f
> {
163 impl<'f
, C
, F
> InspectConsumer
<'f
, C
, F
> {
164 fn new(base
: C
, inspect_op
: &'f F
) -> Self {
167 inspect_op
: inspect_op
,
172 impl<'f
, T
, C
, F
> Consumer
<T
> for InspectConsumer
<'f
, C
, F
>
173 where C
: Consumer
<T
>,
176 type Folder
= InspectFolder
<'f
, C
::Folder
, F
>;
177 type Reducer
= C
::Reducer
;
178 type Result
= C
::Result
;
180 fn split_at(self, index
: usize) -> (Self, Self, Self::Reducer
) {
181 let (left
, right
, reducer
) = self.base
.split_at(index
);
182 (InspectConsumer
::new(left
, self.inspect_op
),
183 InspectConsumer
::new(right
, self.inspect_op
),
187 fn into_folder(self) -> Self::Folder
{
189 base
: self.base
.into_folder(),
190 inspect_op
: self.inspect_op
,
194 fn full(&self) -> bool
{
199 impl<'f
, T
, C
, F
> UnindexedConsumer
<T
> for InspectConsumer
<'f
, C
, F
>
200 where C
: UnindexedConsumer
<T
>,
203 fn split_off_left(&self) -> Self {
204 InspectConsumer
::new(self.base
.split_off_left(), &self.inspect_op
)
207 fn to_reducer(&self) -> Self::Reducer
{
208 self.base
.to_reducer()
212 struct InspectFolder
<'f
, C
, F
: 'f
> {
217 impl<'f
, T
, C
, F
> Folder
<T
> for InspectFolder
<'f
, C
, F
>
221 type Result
= C
::Result
;
223 fn consume(self, item
: T
) -> Self {
224 (self.inspect_op
)(&item
);
226 base
: self.base
.consume(item
),
227 inspect_op
: self.inspect_op
,
231 fn complete(self) -> C
::Result
{
235 fn full(&self) -> bool
{