Coverage Report

Created: 2025-06-23 13:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/build/cargo-vendor-dir/itertools-0.14.0/src/free.rs
Line
Count
Source
1
//! Free functions that create iterator adaptors or call iterator methods.
2
//!
3
//! The benefit of free functions is that they accept any [`IntoIterator`] as
4
//! argument, so the resulting code may be easier to read.
5
6
#[cfg(feature = "use_alloc")]
7
use std::fmt::Display;
8
use std::iter::{self, Zip};
9
#[cfg(feature = "use_alloc")]
10
type VecIntoIter<T> = alloc::vec::IntoIter<T>;
11
12
#[cfg(feature = "use_alloc")]
13
use alloc::string::String;
14
15
use crate::intersperse::{Intersperse, IntersperseWith};
16
use crate::Itertools;
17
18
pub use crate::adaptors::{interleave, put_back};
19
#[cfg(feature = "use_alloc")]
20
pub use crate::kmerge_impl::kmerge;
21
pub use crate::merge_join::{merge, merge_join_by};
22
#[cfg(feature = "use_alloc")]
23
pub use crate::multipeek_impl::multipeek;
24
#[cfg(feature = "use_alloc")]
25
pub use crate::peek_nth::peek_nth;
26
#[cfg(feature = "use_alloc")]
27
pub use crate::put_back_n_impl::put_back_n;
28
#[cfg(feature = "use_alloc")]
29
pub use crate::rciter_impl::rciter;
30
pub use crate::zip_eq_impl::zip_eq;
31
32
/// Iterate `iterable` with a particular value inserted between each element.
33
///
34
/// [`IntoIterator`] enabled version of [`Iterator::intersperse`].
35
///
36
/// ```
37
/// use itertools::intersperse;
38
///
39
/// itertools::assert_equal(intersperse(0..3, 8), vec![0, 8, 1, 8, 2]);
40
/// ```
41
pub fn intersperse<I>(iterable: I, element: I::Item) -> Intersperse<I::IntoIter>
42
where
43
    I: IntoIterator,
44
    <I as IntoIterator>::Item: Clone,
45
{
46
    Itertools::intersperse(iterable.into_iter(), element)
47
}
48
49
/// Iterate `iterable` with a particular value created by a function inserted
50
/// between each element.
51
///
52
/// [`IntoIterator`] enabled version of [`Iterator::intersperse_with`].
53
///
54
/// ```
55
/// use itertools::intersperse_with;
56
///
57
/// let mut i = 10;
58
/// itertools::assert_equal(intersperse_with(0..3, || { i -= 1; i }), vec![0, 9, 1, 8, 2]);
59
/// assert_eq!(i, 8);
60
/// ```
61
pub fn intersperse_with<I, F>(iterable: I, element: F) -> IntersperseWith<I::IntoIter, F>
62
where
63
    I: IntoIterator,
64
    F: FnMut() -> I::Item,
65
{
66
    Itertools::intersperse_with(iterable.into_iter(), element)
67
}
68
69
/// Iterate `iterable` with a running index.
70
///
71
/// [`IntoIterator`] enabled version of [`Iterator::enumerate`].
72
///
73
/// ```
74
/// use itertools::enumerate;
75
///
76
/// for (i, elt) in enumerate(&[1, 2, 3]) {
77
///     /* loop body */
78
///     # let _ = (i, elt);
79
/// }
80
/// ```
81
89
pub fn enumerate<I>(iterable: I) -> iter::Enumerate<I::IntoIter>
82
89
where
83
89
    I: IntoIterator,
84
89
{
85
89
    iterable.into_iter().enumerate()
86
89
}
87
88
/// Iterate `iterable` in reverse.
89
///
90
/// [`IntoIterator`] enabled version of [`Iterator::rev`].
91
///
92
/// ```
93
/// use itertools::rev;
94
///
95
/// for elt in rev(&[1, 2, 3]) {
96
///     /* loop body */
97
///     # let _ = elt;
98
/// }
99
/// ```
100
pub fn rev<I>(iterable: I) -> iter::Rev<I::IntoIter>
101
where
102
    I: IntoIterator,
103
    I::IntoIter: DoubleEndedIterator,
104
{
105
    iterable.into_iter().rev()
106
}
107
108
/// Converts the arguments to iterators and zips them.
109
///
110
/// [`IntoIterator`] enabled version of [`Iterator::zip`].
111
///
112
/// ## Example
113
///
114
/// ```
115
/// use itertools::zip;
116
///
117
/// let mut result: Vec<(i32, char)> = Vec::new();
118
///
119
/// for (a, b) in zip(&[1, 2, 3, 4, 5], &['a', 'b', 'c']) {
120
///     result.push((*a, *b));
121
/// }
122
/// assert_eq!(result, vec![(1, 'a'),(2, 'b'),(3, 'c')]);
123
/// ```
124
#[deprecated(
125
    note = "Use [std::iter::zip](https://doc.rust-lang.org/std/iter/fn.zip.html) instead",
126
    since = "0.10.4"
127
)]
128
pub fn zip<I, J>(i: I, j: J) -> Zip<I::IntoIter, J::IntoIter>
129
where
130
    I: IntoIterator,
131
    J: IntoIterator,
132
{
133
    i.into_iter().zip(j)
134
}
135
136
/// Takes two iterables and creates a new iterator over both in sequence.
137
///
138
/// [`IntoIterator`] enabled version of [`Iterator::chain`].
139
///
140
/// ## Example
141
/// ```
142
/// use itertools::chain;
143
///
144
/// let mut result:Vec<i32> = Vec::new();
145
///
146
/// for element in chain(&[1, 2, 3], &[4]) {
147
///     result.push(*element);
148
/// }
149
/// assert_eq!(result, vec![1, 2, 3, 4]);
150
/// ```
151
pub fn chain<I, J>(
152
    i: I,
153
    j: J,
154
) -> iter::Chain<<I as IntoIterator>::IntoIter, <J as IntoIterator>::IntoIter>
155
where
156
    I: IntoIterator,
157
    J: IntoIterator<Item = I::Item>,
158
{
159
    i.into_iter().chain(j)
160
}
161
162
/// Create an iterator that clones each element from `&T` to `T`.
163
///
164
/// [`IntoIterator`] enabled version of [`Iterator::cloned`].
165
///
166
/// ```
167
/// use itertools::cloned;
168
///
169
/// assert_eq!(cloned(b"abc").next(), Some(b'a'));
170
/// ```
171
pub fn cloned<'a, I, T>(iterable: I) -> iter::Cloned<I::IntoIter>
172
where
173
    I: IntoIterator<Item = &'a T>,
174
    T: Clone + 'a,
175
{
176
    iterable.into_iter().cloned()
177
}
178
179
/// Perform a fold operation over the iterable.
180
///
181
/// [`IntoIterator`] enabled version of [`Iterator::fold`].
182
///
183
/// ```
184
/// use itertools::fold;
185
///
186
/// assert_eq!(fold(&[1., 2., 3.], 0., |a, &b| f32::max(a, b)), 3.);
187
/// ```
188
pub fn fold<I, B, F>(iterable: I, init: B, f: F) -> B
189
where
190
    I: IntoIterator,
191
    F: FnMut(B, I::Item) -> B,
192
{
193
    iterable.into_iter().fold(init, f)
194
}
195
196
/// Test whether the predicate holds for all elements in the iterable.
197
///
198
/// [`IntoIterator`] enabled version of [`Iterator::all`].
199
///
200
/// ```
201
/// use itertools::all;
202
///
203
/// assert!(all(&[1, 2, 3], |elt| *elt > 0));
204
/// ```
205
pub fn all<I, F>(iterable: I, f: F) -> bool
206
where
207
    I: IntoIterator,
208
    F: FnMut(I::Item) -> bool,
209
{
210
    iterable.into_iter().all(f)
211
}
212
213
/// Test whether the predicate holds for any elements in the iterable.
214
///
215
/// [`IntoIterator`] enabled version of [`Iterator::any`].
216
///
217
/// ```
218
/// use itertools::any;
219
///
220
/// assert!(any(&[0, -1, 2], |elt| *elt > 0));
221
/// ```
222
pub fn any<I, F>(iterable: I, f: F) -> bool
223
where
224
    I: IntoIterator,
225
    F: FnMut(I::Item) -> bool,
226
{
227
    iterable.into_iter().any(f)
228
}
229
230
/// Return the maximum value of the iterable.
231
///
232
/// [`IntoIterator`] enabled version of [`Iterator::max`].
233
///
234
/// ```
235
/// use itertools::max;
236
///
237
/// assert_eq!(max(0..10), Some(9));
238
/// ```
239
pub fn max<I>(iterable: I) -> Option<I::Item>
240
where
241
    I: IntoIterator,
242
    I::Item: Ord,
243
{
244
    iterable.into_iter().max()
245
}
246
247
/// Return the minimum value of the iterable.
248
///
249
/// [`IntoIterator`] enabled version of [`Iterator::min`].
250
///
251
/// ```
252
/// use itertools::min;
253
///
254
/// assert_eq!(min(0..10), Some(0));
255
/// ```
256
pub fn min<I>(iterable: I) -> Option<I::Item>
257
where
258
    I: IntoIterator,
259
    I::Item: Ord,
260
{
261
    iterable.into_iter().min()
262
}
263
264
/// Combine all iterator elements into one `String`, separated by `sep`.
265
///
266
/// [`IntoIterator`] enabled version of [`Itertools::join`].
267
///
268
/// ```
269
/// use itertools::join;
270
///
271
/// assert_eq!(join(&[1, 2, 3], ", "), "1, 2, 3");
272
/// ```
273
#[cfg(feature = "use_alloc")]
274
pub fn join<I>(iterable: I, sep: &str) -> String
275
where
276
    I: IntoIterator,
277
    I::Item: Display,
278
{
279
    iterable.into_iter().join(sep)
280
}
281
282
/// Sort all iterator elements into a new iterator in ascending order.
283
///
284
/// [`IntoIterator`] enabled version of [`Itertools::sorted`].
285
///
286
/// ```
287
/// use itertools::sorted;
288
/// use itertools::assert_equal;
289
///
290
/// assert_equal(sorted("rust".chars()), "rstu".chars());
291
/// ```
292
#[cfg(feature = "use_alloc")]
293
pub fn sorted<I>(iterable: I) -> VecIntoIter<I::Item>
294
where
295
    I: IntoIterator,
296
    I::Item: Ord,
297
{
298
    iterable.into_iter().sorted()
299
}
300
301
/// Sort all iterator elements into a new iterator in ascending order.
302
/// This sort is unstable (i.e., may reorder equal elements).
303
///
304
/// [`IntoIterator`] enabled version of [`Itertools::sorted_unstable`].
305
///
306
/// ```
307
/// use itertools::sorted_unstable;
308
/// use itertools::assert_equal;
309
///
310
/// assert_equal(sorted_unstable("rust".chars()), "rstu".chars());
311
/// ```
312
#[cfg(feature = "use_alloc")]
313
pub fn sorted_unstable<I>(iterable: I) -> VecIntoIter<I::Item>
314
where
315
    I: IntoIterator,
316
    I::Item: Ord,
317
{
318
    iterable.into_iter().sorted_unstable()
319
}