Coverage Report

Created: 2025-07-12 07:18

/rust/registry/src/index.crates.io-6f17d22bba15001f/itertools-0.12.1/src/tee.rs
Line
Count
Source (jump to first uncovered line)
1
use super::size_hint;
2
3
use alloc::collections::VecDeque;
4
use alloc::rc::Rc;
5
use std::cell::RefCell;
6
7
/// Common buffer object for the two tee halves
8
#[derive(Debug)]
9
struct TeeBuffer<A, I> {
10
    backlog: VecDeque<A>,
11
    iter: I,
12
    /// The owner field indicates which id should read from the backlog
13
    owner: bool,
14
}
15
16
/// One half of an iterator pair where both return the same elements.
17
///
18
/// See [`.tee()`](crate::Itertools::tee) for more information.
19
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
20
#[derive(Debug)]
21
pub struct Tee<I>
22
where
23
    I: Iterator,
24
{
25
    rcbuffer: Rc<RefCell<TeeBuffer<I::Item, I>>>,
26
    id: bool,
27
}
28
29
0
pub fn new<I>(iter: I) -> (Tee<I>, Tee<I>)
30
0
where
31
0
    I: Iterator,
32
0
{
33
0
    let buffer = TeeBuffer {
34
0
        backlog: VecDeque::new(),
35
0
        iter,
36
0
        owner: false,
37
0
    };
38
0
    let t1 = Tee {
39
0
        rcbuffer: Rc::new(RefCell::new(buffer)),
40
0
        id: true,
41
0
    };
42
0
    let t2 = Tee {
43
0
        rcbuffer: t1.rcbuffer.clone(),
44
0
        id: false,
45
0
    };
46
0
    (t1, t2)
47
0
}
48
49
impl<I> Iterator for Tee<I>
50
where
51
    I: Iterator,
52
    I::Item: Clone,
53
{
54
    type Item = I::Item;
55
0
    fn next(&mut self) -> Option<Self::Item> {
56
0
        // .borrow_mut may fail here -- but only if the user has tied some kind of weird
57
0
        // knot where the iterator refers back to itself.
58
0
        let mut buffer = self.rcbuffer.borrow_mut();
59
0
        if buffer.owner == self.id {
60
0
            match buffer.backlog.pop_front() {
61
0
                None => {}
62
0
                some_elt => return some_elt,
63
            }
64
0
        }
65
0
        match buffer.iter.next() {
66
0
            None => None,
67
0
            Some(elt) => {
68
0
                buffer.backlog.push_back(elt.clone());
69
0
                buffer.owner = !self.id;
70
0
                Some(elt)
71
            }
72
        }
73
0
    }
74
75
0
    fn size_hint(&self) -> (usize, Option<usize>) {
76
0
        let buffer = self.rcbuffer.borrow();
77
0
        let sh = buffer.iter.size_hint();
78
0
79
0
        if buffer.owner == self.id {
80
0
            let log_len = buffer.backlog.len();
81
0
            size_hint::add_scalar(sh, log_len)
82
        } else {
83
0
            sh
84
        }
85
0
    }
86
}
87
88
impl<I> ExactSizeIterator for Tee<I>
89
where
90
    I: ExactSizeIterator,
91
    I::Item: Clone,
92
{
93
}