Coverage Report

Created: 2025-11-28 06:44

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