1use std::{cell::RefCell, rc::Rc};
2
3#[derive(Debug, Clone, PartialEq, Eq)]
4pub struct PeekableBuffer<T>
5 where T: Clone
6{
7 iter: Vec<T>,
8 ctr: Rc<RefCell<usize>>,
9}
10
11impl<T> IntoIterator for PeekableBuffer<T>
12 where T: Clone
13{
14 type Item = T;
15 type IntoIter = std::vec::IntoIter<T>;
16
17 fn into_iter(self) -> Self::IntoIter {
18 self.iter.into_iter()
19 }
20}
21
22impl<T> PeekableBuffer<T>
23 where T: Clone
24{
25 pub fn new<E>(elements: E) -> Self
27 where E: AsRef<[T]>
28 {
29 Self {
30 iter: elements.as_ref().iter().cloned().collect(),
31 ctr: Rc::new(RefCell::new(0)),
32 }
33 }
34
35 pub fn is_at_end(&self) -> bool {
37 let borrowed_ctr = self.ctr.borrow();
38 *borrowed_ctr >= self.iter.len()
39 }
40
41 pub fn len(&self) -> usize {
43 self.iter.len()
44 }
45
46 pub fn lookaround(&self, offset: i64) -> Option<&T> {
50 let i = self.compute_bounded_offset(offset);
51 if i < 0 || self.len() <= i as usize {
52 None
53 } else {
54 Some(&(self.iter[i as usize]))
55 }
56 }
57
58 pub fn peek(&self) -> Option<&T> {
62 self.lookaround(1)
63 }
64
65 pub fn current(&self) -> Option<&T> {
68 self.lookaround(0)
69 }
70
71 pub fn shift(&mut self, offset: i64) -> () {
77 let i = self.compute_bounded_offset(offset);
78 *self.ctr.borrow_mut() = if i == -1 {
79 0
80 } else {
81 i as usize
82 }
83 }
84
85 pub fn advance(&mut self) -> () {
89 self.shift(1);
90 }
91
92 pub fn set_pos(&mut self, pos: usize) -> usize {
96 let i = std::cmp::min(pos, self.iter.len());
97 *self.ctr.borrow_mut() = i;
98 i
99 }
100
101 pub fn pos(&self) -> usize {
104 *self.ctr.borrow_mut()
105 }
106
107 pub fn consume(&mut self) -> Option<&T> {
110 let tmp = self.current();
111 let mut mctr = self.ctr.borrow_mut();
112 *mctr += 1;
113 if *mctr >= self.len() {
114 *mctr = self.len(); }
116 tmp
117 }
118
119 pub fn take_while<P>(&mut self, predicate: P) -> impl Iterator<Item = &T>
124 where P: Fn(&T) -> bool
125 {
126 let mut v = Vec::new();
127 let mut mctr = self.ctr.borrow_mut();
128 while *mctr < self.iter.len() && predicate(&self.iter[*mctr]) {
129 v.push(&self.iter[*mctr]);
130 *mctr += 1;
131 }
132 v.into_iter()
133 }
134
135 pub fn take(&mut self, n: usize) -> impl Iterator<Item = &T> {
141 let mut v = Vec::new();
142 let mut mctr = self.ctr.borrow_mut();
143 for _ in 0..n {
144 if *mctr >= self.iter.len() {
145 break;
146 }
147 v.push(&self.iter[*mctr]);
148 *mctr += 1;
149 }
150 v.into_iter()
151 }
152
153 pub fn accept<P>(&self, predicate: P) -> bool
157 where P: Fn(&T) -> bool
158 {
159 if self.is_at_end() {
160 false
161 } else {
162 predicate(self.current().unwrap())
163 }
164 }
165
166 pub fn slice_from(&self, from_inc: usize) -> PeekableBuffer<T> {
171 self.slice_between(from_inc, usize::MAX)
172 }
173
174 pub fn slice_between(&self, from_inc: usize, to_exc: usize) -> PeekableBuffer<T> {
181 if from_inc > to_exc {
182 panic!("from_inc={} greater than to_exc{}", from_inc, to_exc);
183 }
184 let a: usize = std::cmp::min(self.len(), from_inc);
185 let b: usize = std::cmp::min(self.len(), to_exc);
186 PeekableBuffer::new(&self.iter[a..b])
187 }
188
189 fn compute_bounded_offset(&self, offset: i64) -> i128 {
195 let curr: i128 = *self.ctr.borrow_mut() as i128 + offset as i128; if offset < 0 {
197 std::cmp::max(-1, curr)
198 } else {
199 std::cmp::min(self.iter.len(), curr as usize) as i128
200 }
201 }
202}
203
204#[cfg(test)]
205mod tests {
206 use super::*;
207
208 #[test]
209 fn test_is_at_end() {
210 let elems = vec![1, 2, 3];
211 let mut stream = PeekableBuffer::new(&elems);
212 for _ in elems {
213 stream.advance();
214 }
215 assert!(stream.is_at_end());
216 }
217
218 #[test]
219 fn test_len() {
220 let elems = vec![1, 2, 3, 4];
221 let stream = PeekableBuffer::new(&elems);
222 assert_eq!(stream.len(), elems.len());
223 }
224
225 #[test]
226 fn test_lookaround_peek_current() {
227 let elems = vec![1, 2, 3];
228 let mut stream = PeekableBuffer::new(&elems);
229
230 assert_eq!(stream.len(), 3);
231
232 assert!(!stream.is_at_end());
234 assert_eq!(stream.pos(), 0);
235 assert_eq!(stream.current(), Some(&1));
236 assert_eq!(stream.peek(), Some(&2));
237 assert_eq!(stream.lookaround(-1), None);
238 assert_eq!(stream.lookaround(0), Some(&1));
239 assert_eq!(stream.lookaround(1), Some(&2));
240 assert_eq!(stream.lookaround(2), Some(&3));
241 assert_eq!(stream.lookaround(3), None);
242 assert_eq!(stream.lookaround(4), None);
243
244 assert!(!stream.is_at_end());
245 assert_eq!(stream.current(), Some(&1));
246
247 stream.advance();
249 assert_eq!(stream.pos(), 1);
250 assert_eq!(stream.peek(), Some(&3));
251 stream.shift(-1);
252 assert_eq!(stream.pos(), 0);
253 assert_eq!(stream.peek(), Some(&2));
254 stream.shift(1);
255 assert_eq!(stream.pos(), 1);
256 assert_eq!(stream.peek(), Some(&3));
257 assert!(!stream.is_at_end());
258 assert_eq!(stream.current(), Some(&2));
259 assert_eq!(stream.peek(), Some(&3));
260 assert_eq!(stream.lookaround(-2), None);
261 assert_eq!(stream.lookaround(-1), Some(&1));
262 assert_eq!(stream.lookaround(0), Some(&2));
263 assert_eq!(stream.lookaround(1), Some(&3));
264 assert_eq!(stream.lookaround(2), None);
265 assert_eq!(stream.lookaround(3), None);
266
267 assert!(!stream.is_at_end());
268 assert_eq!(stream.current(), Some(&2));
269 }
270
271 #[test]
272 fn test_shift_advance() {
273 fn limit(stream: &mut PeekableBuffer<i64>) {
274 let offset_from_end = *stream.ctr.borrow_mut() as i64 - stream.len() as i64;
275
276 stream.shift(i64::MAX);
278 assert_eq!(stream.pos(), 3);
279 assert!(stream.is_at_end());
280 assert_eq!(stream.current(), None);
281 stream.shift(-2);
282 assert_eq!(stream.current(), Some(&2));
283
284 assert!(!stream.is_at_end());
286 stream.shift(i64::MIN);
287 assert_eq!(stream.pos(), 0);
288 assert!(!stream.is_at_end());
289 assert_eq!(stream.current(), Some(&1));
290 stream.shift(1);
291 assert_eq!(stream.current(), Some(&2));
292
293 stream.shift(i64::MAX);
295 stream.shift(offset_from_end as i64);
296 }
297
298 let elems = vec![1, 2, 3];
299 let mut stream = PeekableBuffer::new(&elems);
300 for i in 1..=4 {
301 assert_eq!(stream.pos(), (i - 1) as usize);
302 limit(&mut stream);
303 stream.advance();
304 }
305 }
306
307 #[test]
308 fn test_set_pos() {
309 let elems = vec![1, 2, 3];
310 let mut stream = PeekableBuffer::new(&elems);
311 assert_eq!(stream.current(), Some(&1));
312 stream.set_pos(2);
313 assert_eq!(stream.current(), Some(&3));
314 stream.set_pos(1);
315 assert_eq!(stream.current(), Some(&2));
316 stream.set_pos(0);
317 assert_eq!(stream.current(), Some(&1));
318 stream.set_pos(3);
319 assert_eq!(stream.current(), None);
320 stream.set_pos(100);
321 assert_eq!(stream.current(), None);
322 assert!(stream.is_at_end());
323 }
324
325 #[test]
326 fn test_pos_consume() {
327 let elems = vec![1, 2, 3];
328 let mut stream = PeekableBuffer::new(&elems);
329
330 assert_eq!(stream.len(), 3);
331
332 assert_eq!(stream.pos(), 0);
333 assert_eq!(stream.consume(), Some(&1));
334 assert_eq!(stream.pos(), 1);
335 assert_eq!(stream.consume(), Some(&2));
336 assert_eq!(stream.pos(), 2);
337 assert_eq!(stream.consume(), Some(&3));
338 assert_eq!(stream.pos(), 3);
339 assert_eq!(stream.consume(), None);
340 assert_eq!(stream.pos(), 3);
341 assert_eq!(stream.consume(), None);
342 assert_eq!(stream.pos(), 3);
343 }
344
345 #[test]
346 fn test_take_while_consumes_part_of_stream() {
347 let elems = vec![1, 2, 3, 3, 4, 5];
348 let mut stream = PeekableBuffer::new(&elems);
349
350 assert_eq!(stream.len(), 6);
351
352 let taken: Vec<&i64> = stream.take_while(|&i| i < 4).collect();
353 assert_eq!(taken, vec![&1, &2, &3, &3]);
354
355 assert_eq!(stream.pos(), 4);
356 assert!(!stream.is_at_end());
357 assert_eq!(stream.current(), Some(&4));
358 assert_eq!(stream.peek(), Some(&5));
359 }
360
361 #[test]
362 fn test_take_while_predicate_consumes_entire_stream() {
363 let elems = vec![1, 2, 3, 4, 5];
364 let mut stream = PeekableBuffer::new(&elems);
365
366 assert_eq!(stream.len(), 5);
367
368 let taken: Vec<&i64> = stream.take_while(|&i| i < 10).collect();
369 assert_eq!(taken, vec![&1, &2, &3, &4, &5]);
370
371 assert_eq!(stream.pos(), 5);
372 assert!(stream.is_at_end());
373 assert_eq!(stream.current(), None);
374 assert_eq!(stream.peek(), None);
375 assert_eq!(stream.lookaround(-1), Some(&5));
376 }
377
378 #[test]
379 fn test_take_while_predicate_consumes_no_elements() {
380 let elems = vec![1, 2, 3, 4, 5];
381 let mut stream = PeekableBuffer::new(&elems);
382
383 assert_eq!(stream.len(), 5);
384
385 stream.advance();
387
388 let taken: Vec<&i64> = stream.take_while(|&i| i == 1).collect();
389 assert!(taken.is_empty());
390
391 assert_eq!(stream.pos(), 1);
392 assert!(!stream.is_at_end());
393 assert_eq!(stream.current(), Some(&2));
394 assert_eq!(stream.peek(), Some(&3));
395 }
396
397 #[test]
398 fn test_take() {
399 let elems = vec![1, 2, 3, 4, 5];
400 let mut stream = PeekableBuffer::new(&elems);
401 assert_eq!(stream.len(), 5);
402
403 {
404 let taken: Vec<&i64> = stream.take(0).collect();
405 assert!(taken.is_empty());
406 assert_eq!(taken, Vec::<&i64>::new());
407 assert!(stream.pos() == 0);
408 assert!(!stream.is_at_end());
409 }
410 {
411 let taken: Vec<&i64> = stream.take(2).collect();
412 assert!(!taken.is_empty());
413 assert_eq!(taken, vec![&1, &2]);
414 assert!(stream.pos() == 2);
415 assert!(!stream.is_at_end());
416 }
417 {
418 let taken: Vec<&i64> = stream.take(2).collect();
419 assert!(!taken.is_empty());
420 assert_eq!(taken, vec![&3, &4]);
421 assert!(stream.pos() == 4);
422 assert!(!stream.is_at_end());
423 }
424 {
425 let taken: Vec<&i64> = stream.take(2).collect();
426 assert!(!taken.is_empty());
427 assert_eq!(taken, vec![&5]);
428 assert!(stream.pos() == 5);
429 assert!(stream.is_at_end());
430 }
431 {
432 let taken: Vec<&i64> = stream.take(10).collect();
433 assert!(taken.is_empty());
434 assert_eq!(taken, Vec::<&i64>::new());
435 assert!(stream.pos() == 5);
436 assert!(stream.is_at_end());
437 }
438 }
439
440 #[test]
441 fn test_accept() {
442 let elems = vec![1, 2, 3];
443 let mut stream = PeekableBuffer::new(&elems);
444 assert!(stream.accept(|&x| x < 2));
445 stream.advance();
446 assert!(stream.accept(|&x| x == 2));
447 stream.advance();
448 assert!(stream.accept(|&x| x >= 3));
449 assert!(stream.accept(|&x| x != 3) == false);
450 stream.advance();
451 assert!(stream.accept(|&_| true) == false);
452 }
453
454 #[test]
455 pub fn test_slice_from() {
456 let elems = vec![1, 2, 3, 4, 5];
457 let stream = PeekableBuffer::new(&elems);
458 assert_eq!(stream.slice_from(0), PeekableBuffer::new(&vec![1, 2, 3, 4, 5]));
459 assert_eq!(stream.slice_from(1), PeekableBuffer::new(&vec![2, 3, 4, 5]));
460 assert_eq!(stream.slice_from(4), PeekableBuffer::new(&vec![5]));
461 assert_eq!(stream.slice_from(5), PeekableBuffer::new(&vec![]));
462 assert_eq!(stream.slice_from(10), PeekableBuffer::new(&vec![]));
463 }
464
465 #[test]
466 pub fn test_slice_between() {
467 let elems = vec![1, 2, 3, 4, 5];
468 let stream = PeekableBuffer::new(&elems);
469
470 assert_eq!(stream.slice_between(0, 5), PeekableBuffer::new(&vec![1, 2, 3, 4, 5]));
472 assert_eq!(stream.slice_between(1, 5), PeekableBuffer::new(&vec![2, 3, 4, 5]));
473 assert_eq!(stream.slice_between(4, 5), PeekableBuffer::new(&vec![5]));
474 assert_eq!(stream.slice_between(5, 5), PeekableBuffer::new(&vec![]));
475
476 assert_eq!(stream.slice_between(0, 10), PeekableBuffer::new(&vec![1, 2, 3, 4, 5]));
478 assert_eq!(stream.slice_between(1, 10), PeekableBuffer::new(&vec![2, 3, 4, 5]));
479 assert_eq!(stream.slice_between(4, 10), PeekableBuffer::new(&vec![5]));
480 assert_eq!(stream.slice_between(5, 10), PeekableBuffer::new(&vec![]));
481
482 assert_eq!(stream.slice_between(0, 1), PeekableBuffer::new(&vec![1]));
484 assert_eq!(stream.slice_between(1, 3), PeekableBuffer::new(&vec![2, 3]));
485 assert_eq!(stream.slice_between(2, 4), PeekableBuffer::new(&vec![3, 4]));
486 assert_eq!(stream.slice_between(3, 5), PeekableBuffer::new(&vec![4, 5]));
487 assert_eq!(stream.slice_between(1, 1), PeekableBuffer::new(&vec![]));
488 assert_eq!(stream.slice_between(3, 3), PeekableBuffer::new(&vec![]));
489 assert_eq!(stream.slice_between(10, 10), PeekableBuffer::new(&vec![]));
490
491 assert_eq!(stream.slice_between(10, 20), PeekableBuffer::new(&vec![]));
493 }
494
495 #[test]
496 #[should_panic]
497 pub fn test_slice_between_panicking() {
498 let elems = vec![1, 2, 3, 4, 5];
499 let stream = PeekableBuffer::new(&elems);
500 assert_eq!(stream.slice_between(20, 1), PeekableBuffer::new(&vec![]));
501 assert_eq!(stream.slice_between(2, 1), PeekableBuffer::new(&vec![]));
502 assert_eq!(stream.slice_between(20, 10), PeekableBuffer::new(&vec![]));
503 }
504
505 #[test]
506 pub fn test_readme_example() {
507 let v = vec![1, 2, 3, 4, 5];
508 let mut stream = PeekableBuffer::new(&v);
509
510 assert!(!stream.is_at_end());
511 assert_eq!(stream.pos(), 0);
512 assert_eq!(stream.current(), Some(&1));
513
514 stream.advance();
515 assert_eq!(stream.pos(), 1);
516 assert_eq!(stream.current(), Some(&2));
517
518 assert_eq!(stream.lookaround(-1), Some(&1));
519 assert_eq!(stream.lookaround(-10), None);
520
521 stream.shift(3);
522 assert_eq!(stream.current(), Some(&5));
523
524 assert_eq!(stream.consume(), Some(&5));
525 assert!(stream.is_at_end());
526 assert_eq!(stream.current(), None);
527 }
528}