1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//! Misc helper functions and types for use in parsing network documents

pub(crate) mod intern;
pub(crate) mod str;

use std::iter::Peekable;

/// An iterator adaptor that pauses when a given predicate is true.
///
/// Unlike std::iter::TakeWhile, it doesn't consume the first non-returned
/// element.
///
/// We guarantee that the predicate is called no more than once for
/// each item.
pub(crate) struct PauseAt<'a, I: Iterator, F: FnMut(&I::Item) -> bool> {
    /// An underlying iterator that we should take items from
    peek: &'a mut Peekable<I>,
    /// A predicate telling us which items mean that we should pause
    pred: F,
    /// Memoized value of self.pred(self.peek()), so we never
    /// calculate it more than once.
    paused: Option<bool>,
}

impl<'a, I: Iterator, F: FnMut(&I::Item) -> bool> PauseAt<'a, I, F> {
    /// Construct a PauseAt that will pause the iterator `peek` when the
    /// predicate `pred` is about to be true.
    pub(crate) fn from_peekable(peek: &'a mut Peekable<I>, pred: F) -> Self
    where
        F: FnMut(&I::Item) -> bool,
    {
        PauseAt {
            peek,
            pred,
            paused: None,
        }
    }
    /// Replace the predicate on a PauseAt, returning a new PauseAt.
    pub(crate) fn new_pred<F2>(self, pred: F2) -> PauseAt<'a, I, F2>
    where
        F2: FnMut(&I::Item) -> bool,
    {
        PauseAt::from_peekable(self.peek, pred)
    }
    /// Unwrap this PauseAt, returning its underlying Peekable.
    #[allow(unused)]
    pub(crate) fn remaining(self) -> &'a mut Peekable<I> {
        self.peek
    }
    /// Return the next item that will be yielded from this iterator, or
    /// None if this iterator is about to yield None.
    #[allow(unused)]
    pub(crate) fn peek(&mut self) -> Option<&I::Item> {
        // TODO: I wish it weren't necessary for this function to take
        // a mutable reference.
        if self.check_paused() {
            None
        } else {
            self.peek.peek()
        }
    }
    /// Helper: Return true if we will pause before the next element,
    /// and false otherwise.  Store the value in self.paused, so that
    /// we don't invoke self.pred more than once.
    fn check_paused(&mut self) -> bool {
        if let Some(p) = self.paused {
            return p;
        }
        if let Some(nextval) = self.peek.peek() {
            let p = (self.pred)(nextval);
            self.paused = Some(p);
            p
        } else {
            self.paused = Some(false);
            false
        }
    }
}

impl<'a, I: Iterator, F: FnMut(&I::Item) -> bool> Iterator for PauseAt<'a, I, F> {
    type Item = I::Item;
    fn next(&mut self) -> Option<Self::Item> {
        if self.check_paused() {
            None
        } else {
            self.paused = None;
            self.peek.next()
        }
    }
}

/// A Private module for declaring a "sealed" trait.
pub(crate) mod private {
    /// A non-exported trait, used to prevent others from implementing a trait.
    ///
    /// For more inforamation on this pattern, see [the Rust API
    /// guidelines](https://rust-lang.github.io/api-guidelines/future-proofing.html#c-sealed).
    pub trait Sealed {}
}

#[cfg(test)]
mod tests {

    #[test]
    fn test_pause_at() {
        use super::PauseAt;
        let mut iter = (1..10).into_iter().peekable();
        let mut iter = PauseAt::from_peekable(&mut iter, |x| *x == 3);

        assert_eq!(iter.next(), Some(1));
        assert_eq!(iter.next(), Some(2));
        assert_eq!(iter.next(), None);

        let mut iter = iter.new_pred(|x| *x > 5);
        assert_eq!(iter.next(), Some(3));
        assert_eq!(iter.next(), Some(4));
        assert_eq!(iter.next(), Some(5));
        assert_eq!(iter.peek(), None);
        assert_eq!(iter.next(), None);

        let iter = iter.remaining();
        assert_eq!(iter.next(), Some(6));
        assert_eq!(iter.peek(), Some(&7));
        assert_eq!(iter.next(), Some(7));
        assert_eq!(iter.next(), Some(8));
        assert_eq!(iter.next(), Some(9));
        assert_eq!(iter.peek(), None);
        assert_eq!(iter.next(), None);
    }

    #[test]
    fn test_parse_at_mutable() {
        use super::PauseAt;
        let mut count = 0;
        let mut iter = (1..10).into_iter().peekable();
        // pause at the third item, using mutable state in the closure.
        let mut iter = PauseAt::from_peekable(&mut iter, |_| {
            count += 1;
            count == 4
        });
        assert_eq!(iter.peek(), Some(&1)); // we can do this multiple times,
        assert_eq!(iter.peek(), Some(&1)); // but count isn't advanced.
        assert_eq!(iter.next(), Some(1));

        assert_eq!(iter.next(), Some(2));
        assert_eq!(iter.peek(), Some(&3));
        assert_eq!(iter.next(), Some(3));
        assert_eq!(iter.peek(), None);
        assert_eq!(iter.next(), None);
    }
}