Coverage Report

Created: 2025-11-16 06:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/itertools-0.10.5/src/intersperse.rs
Line
Count
Source
1
use std::iter::{Fuse, FusedIterator};
2
use super::size_hint;
3
4
pub trait IntersperseElement<Item> {
5
    fn generate(&mut self) -> Item;
6
}
7
8
#[derive(Debug, Clone)]
9
pub struct IntersperseElementSimple<Item>(Item);
10
11
impl<Item: Clone> IntersperseElement<Item> for IntersperseElementSimple<Item> {
12
0
    fn generate(&mut self) -> Item {
13
0
        self.0.clone()
14
0
    }
15
}
16
17
/// An iterator adaptor to insert a particular value
18
/// between each element of the adapted iterator.
19
///
20
/// Iterator element type is `I::Item`
21
///
22
/// This iterator is *fused*.
23
///
24
/// See [`.intersperse()`](crate::Itertools::intersperse) for more information.
25
pub type Intersperse<I> = IntersperseWith<I, IntersperseElementSimple<<I as Iterator>::Item>>;
26
27
/// Create a new Intersperse iterator
28
0
pub fn intersperse<I>(iter: I, elt: I::Item) -> Intersperse<I>
29
0
    where I: Iterator,
30
{
31
0
    intersperse_with(iter, IntersperseElementSimple(elt))
32
0
}
33
34
impl<Item, F: FnMut()->Item> IntersperseElement<Item> for F {
35
0
    fn generate(&mut self) -> Item {
36
0
        self()
37
0
    }
38
}
39
40
/// An iterator adaptor to insert a particular value created by a function
41
/// between each element of the adapted iterator.
42
///
43
/// Iterator element type is `I::Item`
44
///
45
/// This iterator is *fused*.
46
///
47
/// See [`.intersperse_with()`](crate::Itertools::intersperse_with) for more information.
48
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
49
#[derive(Clone, Debug)]
50
pub struct IntersperseWith<I, ElemF>
51
    where I: Iterator,
52
{
53
    element: ElemF,
54
    iter: Fuse<I>,
55
    peek: Option<I::Item>,
56
}
57
58
/// Create a new `IntersperseWith` iterator
59
0
pub fn intersperse_with<I, ElemF>(iter: I, elt: ElemF) -> IntersperseWith<I, ElemF>
60
0
    where I: Iterator,
61
{
62
0
    let mut iter = iter.fuse();
63
0
    IntersperseWith {
64
0
        peek: iter.next(),
65
0
        iter,
66
0
        element: elt,
67
0
    }
68
0
}
69
70
impl<I, ElemF> Iterator for IntersperseWith<I, ElemF>
71
    where I: Iterator,
72
          ElemF: IntersperseElement<I::Item>
73
{
74
    type Item = I::Item;
75
    #[inline]
76
0
    fn next(&mut self) -> Option<Self::Item> {
77
0
        if self.peek.is_some() {
78
0
            self.peek.take()
79
        } else {
80
0
            self.peek = self.iter.next();
81
0
            if self.peek.is_some() {
82
0
                Some(self.element.generate())
83
            } else {
84
0
                None
85
            }
86
        }
87
0
    }
88
89
0
    fn size_hint(&self) -> (usize, Option<usize>) {
90
        // 2 * SH + { 1 or 0 }
91
0
        let has_peek = self.peek.is_some() as usize;
92
0
        let sh = self.iter.size_hint();
93
0
        size_hint::add_scalar(size_hint::add(sh, sh), has_peek)
94
0
    }
95
96
0
    fn fold<B, F>(mut self, init: B, mut f: F) -> B where
97
0
        Self: Sized, F: FnMut(B, Self::Item) -> B,
98
    {
99
0
        let mut accum = init;
100
101
0
        if let Some(x) = self.peek.take() {
102
0
            accum = f(accum, x);
103
0
        }
104
105
0
        let element = &mut self.element;
106
107
0
        self.iter.fold(accum,
108
0
            |accum, x| {
109
0
                let accum = f(accum, element.generate());
110
0
                f(accum, x)
111
0
        })
112
0
    }
113
}
114
115
impl<I, ElemF> FusedIterator for IntersperseWith<I, ElemF>
116
    where I: Iterator,
117
          ElemF: IntersperseElement<I::Item>
118
{}