1 use super::plumbing
::*;
4 use std
::fmt
::{self, Debug}
;
7 /// `Inspect` is an iterator that calls a function with a reference to each
8 /// element before yielding it.
10 /// This struct is created by the [`inspect()`] method on [`ParallelIterator`]
12 /// [`inspect()`]: trait.ParallelIterator.html#method.inspect
13 /// [`ParallelIterator`]: trait.ParallelIterator.html
14 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
16 pub struct Inspect
<I
: ParallelIterator
, F
> {
21 impl<I
: ParallelIterator
+ Debug
, F
> Debug
for Inspect
<I
, F
> {
22 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
23 f
.debug_struct("Inspect").field("base", &self.base
).finish()
27 impl<I
, F
> Inspect
<I
, F
>
31 /// Creates a new `Inspect` iterator.
32 pub(super) fn new(base
: I
, inspect_op
: F
) -> Self {
33 Inspect { base, inspect_op }
37 impl<I
, F
> ParallelIterator
for Inspect
<I
, F
>
40 F
: Fn(&I
::Item
) + Sync
+ Send
,
44 fn drive_unindexed
<C
>(self, consumer
: C
) -> C
::Result
46 C
: UnindexedConsumer
<Self::Item
>,
48 let consumer1
= InspectConsumer
::new(consumer
, &self.inspect_op
);
49 self.base
.drive_unindexed(consumer1
)
52 fn opt_len(&self) -> Option
<usize> {
57 impl<I
, F
> IndexedParallelIterator
for Inspect
<I
, F
>
59 I
: IndexedParallelIterator
,
60 F
: Fn(&I
::Item
) + Sync
+ Send
,
62 fn drive
<C
>(self, consumer
: C
) -> C
::Result
64 C
: Consumer
<Self::Item
>,
66 let consumer1
= InspectConsumer
::new(consumer
, &self.inspect_op
);
67 self.base
.drive(consumer1
)
70 fn len(&self) -> usize {
74 fn with_producer
<CB
>(self, callback
: CB
) -> CB
::Output
76 CB
: ProducerCallback
<Self::Item
>,
78 return self.base
.with_producer(Callback
{
80 inspect_op
: self.inspect_op
,
83 struct Callback
<CB
, F
> {
88 impl<T
, F
, CB
> ProducerCallback
<T
> for Callback
<CB
, F
>
90 CB
: ProducerCallback
<T
>,
93 type Output
= CB
::Output
;
95 fn callback
<P
>(self, base
: P
) -> CB
::Output
97 P
: Producer
<Item
= T
>,
99 let producer
= InspectProducer
{
101 inspect_op
: &self.inspect_op
,
103 self.callback
.callback(producer
)
109 /// ////////////////////////////////////////////////////////////////////////
111 struct InspectProducer
<'f
, P
, F
> {
116 impl<'f
, P
, F
> Producer
for InspectProducer
<'f
, P
, F
>
119 F
: Fn(&P
::Item
) + Sync
,
122 type IntoIter
= iter
::Inspect
<P
::IntoIter
, &'f F
>;
124 fn into_iter(self) -> Self::IntoIter
{
125 self.base
.into_iter().inspect(self.inspect_op
)
128 fn min_len(&self) -> usize {
132 fn max_len(&self) -> usize {
136 fn split_at(self, index
: usize) -> (Self, Self) {
137 let (left
, right
) = self.base
.split_at(index
);
141 inspect_op
: self.inspect_op
,
145 inspect_op
: self.inspect_op
,
150 fn fold_with
<G
>(self, folder
: G
) -> G
152 G
: Folder
<Self::Item
>,
154 let folder1
= InspectFolder
{
156 inspect_op
: self.inspect_op
,
158 self.base
.fold_with(folder1
).base
162 /// ////////////////////////////////////////////////////////////////////////
163 /// Consumer implementation
165 struct InspectConsumer
<'f
, C
, F
> {
170 impl<'f
, C
, F
> InspectConsumer
<'f
, C
, F
> {
171 fn new(base
: C
, inspect_op
: &'f F
) -> Self {
172 InspectConsumer { base, inspect_op }
176 impl<'f
, T
, C
, F
> Consumer
<T
> for InspectConsumer
<'f
, C
, F
>
181 type Folder
= InspectFolder
<'f
, C
::Folder
, F
>;
182 type Reducer
= C
::Reducer
;
183 type Result
= C
::Result
;
185 fn split_at(self, index
: usize) -> (Self, Self, Self::Reducer
) {
186 let (left
, right
, reducer
) = self.base
.split_at(index
);
188 InspectConsumer
::new(left
, self.inspect_op
),
189 InspectConsumer
::new(right
, self.inspect_op
),
194 fn into_folder(self) -> Self::Folder
{
196 base
: self.base
.into_folder(),
197 inspect_op
: self.inspect_op
,
201 fn full(&self) -> bool
{
206 impl<'f
, T
, C
, F
> UnindexedConsumer
<T
> for InspectConsumer
<'f
, C
, F
>
208 C
: UnindexedConsumer
<T
>,
211 fn split_off_left(&self) -> Self {
212 InspectConsumer
::new(self.base
.split_off_left(), &self.inspect_op
)
215 fn to_reducer(&self) -> Self::Reducer
{
216 self.base
.to_reducer()
220 struct InspectFolder
<'f
, C
, F
> {
225 impl<'f
, T
, C
, F
> Folder
<T
> for InspectFolder
<'f
, C
, F
>
230 type Result
= C
::Result
;
232 fn consume(self, item
: T
) -> Self {
233 (self.inspect_op
)(&item
);
235 base
: self.base
.consume(item
),
236 inspect_op
: self.inspect_op
,
240 fn consume_iter
<I
>(mut self, iter
: I
) -> Self
242 I
: IntoIterator
<Item
= T
>,
246 .consume_iter(iter
.into_iter().inspect(self.inspect_op
));
250 fn complete(self) -> C
::Result
{
254 fn full(&self) -> bool
{