1 //! # `peeking_take_while` 2 //! 3 //! Provides the `peeking_take_while` iterator adaptor method. 4 //! 5 //! The `peeking_take_while` method is very similar to `take_while`, but behaves 6 //! differently when used with a borrowed iterator (perhaps returned by 7 //! `Iterator::by_ref`). 8 //! 9 //! `peeking_take_while` peeks at the next item in the iterator and runs the 10 //! predicate on that peeked item. This avoids consuming the first item yielded 11 //! by the underlying iterator for which the predicate returns `false`. On the 12 //! other hand, `take_while` will consume that first item for which the 13 //! predicate returns `false`, and it will be lost. 14 //! 15 //! ``` 16 //! extern crate peeking_take_while; 17 //! 18 //! // Bring the `peeking_take_while` method for peekable iterators into 19 //! // scope. 20 //! use peeking_take_while::PeekableExt; 21 //! 22 //! # fn main() { 23 //! // Let's say we have two collections we want to iterate through: `xs` and 24 //! // `ys`. We want to perform one operation on all the leading contiguous 25 //! // elements that match some predicate, and a different thing with the rest of 26 //! // the elements. With the `xs`, we will use the normal `take_while`. With the 27 //! // `ys`, we will use `peeking_take_while`. 28 //! 29 //! let xs: Vec<u8> = (0..100).collect(); 30 //! let ys = xs.clone(); 31 //! 32 //! let mut iter_xs = xs.into_iter(); 33 //! let mut iter_ys = ys.into_iter().peekable(); 34 //! 35 //! { 36 //! // Let's do one thing with all the items that are less than 10. 37 //! # fn do_things_with<T>(_: T) {} 38 //! 39 //! let xs_less_than_ten = iter_xs.by_ref().take_while(|x| *x < 10); 40 //! for x in xs_less_than_ten { 41 //! do_things_with(x); 42 //! } 43 //! 44 //! let ys_less_than_ten = iter_ys.by_ref().peeking_take_while(|y| *y < 10); 45 //! for y in ys_less_than_ten { 46 //! do_things_with(y); 47 //! } 48 //! } 49 //! 50 //! // And now we will do some other thing with the items that are greater than 51 //! // or equal to 10. 52 //! 53 //! // ...except, when using plain old `take_while` we lost 10! 54 //! assert_eq!(iter_xs.next(), Some(11)); 55 //! 56 //! // However, when using `peeking_take_while` we did not! Great! 57 //! assert_eq!(iter_ys.next(), Some(10)); 58 //! # } 59 //! ``` 60 61 use std::iter::Peekable; 62 63 /// The iterator returned by `peeking_take_while`. 64 /// 65 /// See the [module documentation](./index.html) for details. 66 pub struct PeekingTakeWhile<'a, I, P> 67 where I: 'a + Iterator 68 { 69 iter: &'a mut Peekable<I>, 70 predicate: P, 71 } 72 73 impl<'a, I, P> Iterator for PeekingTakeWhile<'a, I, P> 74 where I: Iterator, 75 I::Item: ::std::fmt::Debug, 76 P: FnMut(&<I as Iterator>::Item) -> bool 77 { 78 type Item = <I as Iterator>::Item; 79 next(&mut self) -> Option<Self::Item>80 fn next(&mut self) -> Option<Self::Item> { 81 let predicate = &mut self.predicate; 82 if self.iter.peek().map_or(false, |x| !(predicate)(x)) { 83 None 84 } else { 85 self.iter.next() 86 } 87 } 88 } 89 90 /// The `Iterator` extension trait that provides the `peeking_take_while` 91 /// method. 92 /// 93 /// See the [module documentation](./index.html) for details. 94 pub trait PeekableExt<'a, I>: Iterator 95 where I: 'a + Iterator 96 { 97 /// The `Iterator` extension trait that provides the `peeking_take_while` 98 /// method. 99 /// 100 /// See the [module documentation](./index.html) for details. peeking_take_while<P>(&'a mut self, predicate: P) -> PeekingTakeWhile<'a, I, P> where Self: Sized, P: FnMut(&<Self as Iterator>::Item) -> bool101 fn peeking_take_while<P>(&'a mut self, predicate: P) -> PeekingTakeWhile<'a, I, P> 102 where Self: Sized, 103 P: FnMut(&<Self as Iterator>::Item) -> bool; 104 } 105 106 impl<'a, I> PeekableExt<'a, I> for Peekable<I> 107 where I: 'a + Iterator 108 { peeking_take_while<P>(&'a mut self, predicate: P) -> PeekingTakeWhile<I, P> where P: FnMut(&<Self as Iterator>::Item) -> bool109 fn peeking_take_while<P>(&'a mut self, predicate: P) -> PeekingTakeWhile<I, P> 110 where P: FnMut(&<Self as Iterator>::Item) -> bool 111 { 112 PeekingTakeWhile { 113 iter: self, 114 predicate: predicate, 115 } 116 } 117 } 118