Coverage Report

Created: 2025-11-11 07:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/itertools-0.14.0/src/iter_index.rs
Line
Count
Source
1
use core::iter::{Skip, Take};
2
use core::ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive};
3
4
#[cfg(doc)]
5
use crate::Itertools;
6
7
mod private_iter_index {
8
    use core::ops;
9
10
    pub trait Sealed {}
11
12
    impl Sealed for ops::Range<usize> {}
13
    impl Sealed for ops::RangeInclusive<usize> {}
14
    impl Sealed for ops::RangeTo<usize> {}
15
    impl Sealed for ops::RangeToInclusive<usize> {}
16
    impl Sealed for ops::RangeFrom<usize> {}
17
    impl Sealed for ops::RangeFull {}
18
}
19
20
/// Used by [`Itertools::get`] to know which iterator
21
/// to turn different ranges into.
22
pub trait IteratorIndex<I>: private_iter_index::Sealed
23
where
24
    I: Iterator,
25
{
26
    /// The type returned for this type of index.
27
    type Output: Iterator<Item = I::Item>;
28
29
    /// Returns an adapted iterator for the current index.
30
    ///
31
    /// Prefer calling [`Itertools::get`] instead
32
    /// of calling this directly.
33
    fn index(self, from: I) -> Self::Output;
34
}
35
36
impl<I> IteratorIndex<I> for Range<usize>
37
where
38
    I: Iterator,
39
{
40
    type Output = Skip<Take<I>>;
41
42
0
    fn index(self, iter: I) -> Self::Output {
43
0
        iter.take(self.end).skip(self.start)
44
0
    }
45
}
46
47
impl<I> IteratorIndex<I> for RangeInclusive<usize>
48
where
49
    I: Iterator,
50
{
51
    type Output = Take<Skip<I>>;
52
53
0
    fn index(self, iter: I) -> Self::Output {
54
        // end - start + 1 without overflowing if possible
55
0
        let length = if *self.end() == usize::MAX {
56
0
            assert_ne!(*self.start(), 0);
57
0
            self.end() - self.start() + 1
58
        } else {
59
0
            (self.end() + 1).saturating_sub(*self.start())
60
        };
61
0
        iter.skip(*self.start()).take(length)
62
0
    }
63
}
64
65
impl<I> IteratorIndex<I> for RangeTo<usize>
66
where
67
    I: Iterator,
68
{
69
    type Output = Take<I>;
70
71
0
    fn index(self, iter: I) -> Self::Output {
72
0
        iter.take(self.end)
73
0
    }
74
}
75
76
impl<I> IteratorIndex<I> for RangeToInclusive<usize>
77
where
78
    I: Iterator,
79
{
80
    type Output = Take<I>;
81
82
0
    fn index(self, iter: I) -> Self::Output {
83
0
        assert_ne!(self.end, usize::MAX);
84
0
        iter.take(self.end + 1)
85
0
    }
86
}
87
88
impl<I> IteratorIndex<I> for RangeFrom<usize>
89
where
90
    I: Iterator,
91
{
92
    type Output = Skip<I>;
93
94
0
    fn index(self, iter: I) -> Self::Output {
95
0
        iter.skip(self.start)
96
0
    }
97
}
98
99
impl<I> IteratorIndex<I> for RangeFull
100
where
101
    I: Iterator,
102
{
103
    type Output = I;
104
105
0
    fn index(self, iter: I) -> Self::Output {
106
0
        iter
107
0
    }
108
}
109
110
0
pub fn get<I, R>(iter: I, index: R) -> R::Output
111
0
where
112
0
    I: IntoIterator,
113
0
    R: IteratorIndex<I::IntoIter>,
114
{
115
0
    index.index(iter.into_iter())
116
0
}