1#![deny(
25 missing_docs,
26 missing_debug_implementations,
27 unreachable_pub,
28 broken_intra_doc_links
29)]
30#![warn(rust_2018_idioms)]
31
32use std::collections::VecDeque;
33
34#[derive(Debug, Clone)]
39pub struct PushBackIterator<I: Iterator> {
40 buffer: VecDeque<I::Item>,
41 inner: I,
42}
43
44impl<I: Iterator> PushBackIterator<I> {
45 pub fn push_back(&mut self, item: I::Item) {
50 self.buffer.push_back(item)
51 }
52
53 #[inline]
58 pub fn peek(&mut self) -> Option<&I::Item> {
59 self.peek_nth(0)
60 }
61
62 pub fn peek_nth(&mut self, n: usize) -> Option<&I::Item> {
67 if n >= self.buffer.len() {
68 for _ in 0..=(n - self.buffer.len()) {
69 self.buffer.push_front(self.inner.next()?);
70 }
71 }
72 Some(&self.buffer[self.buffer.len() - n - 1])
73 }
74
75 pub fn reserve(&mut self, additional: usize) {
82 self.buffer.reserve(additional)
83 }
84
85 pub fn shrink_to_fit(&mut self) {
88 self.buffer.shrink_to_fit()
89 }
90}
91
92impl<I: Iterator> From<I> for PushBackIterator<I> {
93 fn from(inner: I) -> Self {
94 PushBackIterator {
95 buffer: VecDeque::new(),
96 inner,
97 }
98 }
99}
100
101impl<I: Iterator> Iterator for PushBackIterator<I> {
102 type Item = I::Item;
103
104 fn next(&mut self) -> Option<Self::Item> {
105 self.buffer.pop_back().or_else(|| self.inner.next())
106 }
107
108 fn size_hint(&self) -> (usize, Option<usize>) {
109 let (lower, upper) = self.inner.size_hint();
110 (
111 lower + self.buffer.len(),
112 upper.map(|upper| upper + self.buffer.len()),
113 )
114 }
115
116 fn count(self) -> usize
117 where
118 Self: Sized,
119 {
120 self.buffer.len() + self.inner.count()
121 }
122
123 fn last(self) -> Option<Self::Item>
124 where
125 Self: Sized,
126 {
127 self.inner.last()
128 }
129
130 fn nth(&mut self, n: usize) -> Option<Self::Item> {
131 if n < self.buffer.len() {
132 self.buffer.truncate(self.buffer.len() - n);
133 self.buffer.pop_back()
134 } else {
135 let n = n - self.buffer.len();
136 self.buffer.clear();
137 self.inner.nth(n)
138 }
139 }
140}
141
142impl<I: ExactSizeIterator> ExactSizeIterator for PushBackIterator<I> {
143 fn len(&self) -> usize {
144 self.buffer.len() + self.inner.len()
145 }
146}
147
148impl<I: DoubleEndedIterator> DoubleEndedIterator for PushBackIterator<I> {
149 fn next_back(&mut self) -> Option<Self::Item> {
150 self.inner.next_back().or_else(|| self.buffer.pop_front())
151 }
152}
153
154#[cfg(test)]
155mod tests {
156 use super::*;
157
158 #[test]
159 fn push_back() {
160 let items = vec![0, 1, 2, 3];
161 let mut iter = PushBackIterator::from(items.into_iter());
162 assert_eq!(iter.next(), Some(0));
163 assert_eq!(iter.next(), Some(1));
164 iter.push_back(1);
165 assert_eq!(iter.next(), Some(1));
166 assert_eq!(iter.next(), Some(2));
167 iter.push_back(2);
168 iter.push_back(1);
169 assert_eq!(iter.next(), Some(1));
170 assert_eq!(iter.next(), Some(2));
171
172 assert_eq!(iter.next(), Some(3));
173 assert_eq!(iter.next(), None);
174
175 iter.push_back(0);
176 assert_eq!(iter.next(), Some(0));
177 assert_eq!(iter.next(), None);
178 }
179
180 #[test]
181 fn peek_nth() {
182 let items = vec![0, 1, 2, 3, 4, 5];
183 let mut iter = PushBackIterator::from(items.into_iter());
184 assert_eq!(iter.peek_nth(2), Some(&2));
185 assert_eq!(iter.peek_nth(2), Some(&2));
186 assert_eq!(iter.next(), Some(0));
187 assert_eq!(iter.peek_nth(2), Some(&3));
188 iter.push_back(0);
189 assert_eq!(iter.peek_nth(2), Some(&2));
190 assert_eq!(iter.next(), Some(0));
191 assert_eq!(iter.next(), Some(1));
192 assert_eq!(iter.next(), Some(2));
193 assert_eq!(iter.next(), Some(3));
194 }
195}