Peek

Struct Peek 

Source
pub struct Peek<'r, T: Iterator> { /* private fields */ }
Expand description

A view into a peeked element of a Peekable iterator.

When using peek on a Peekable iterator, it returns this struct rather than a direct reference to the next element. This wrapper provides additional operations that would not be possible with a simple reference, such as peeking further ahead or consuming elements conditionally.

§Lifetime

A Peek instance borrows the Peekable iterator mutably, ensuring that no other operations can be performed on the iterator while the peek is active. This maintains iterator safety while allowing complex peek operations.

§Example

let mut iter = Peekable::new([1, 2, 3].into_iter());

// Get a Peek instance
let mut peek = iter.peek();

// Compare the peeked value
assert_eq!(peek, Some(&1));

// Look at the next element through the Peek instance
assert_eq!(peek.peek(), Some(&2));

// We can also modify the peeked value
if let Some(val) = peek.get_mut() {
    *val *= 10;
}

// The modification is reflected when we consume the value
assert_eq!(iter.next(), Some(10));
 
// We also can move the iterator forward, consuming the currently peeked element
let peek = iter.peek();
 
let elem = if peek == Some(&2) {
    peek.consume()
} else {
    None
};
 
assert_eq!(elem, Some(2));
assert_eq!(iter.next(), Some(3));

§Advanced Usage

The Peek type supports conditional consumption of elements based on looking ahead:

let mut iter = Peekable::new([1, 2, 3].into_iter());
let peek = iter.peek();

// We can consume elements based on what comes next
peek.drain_if(|&next| next == 2)
    .map_or_else(
        |_peek| unreachable!("Next value was 2"),
        |(curr, next)| {
            assert_eq!(curr, Some(1));
            assert_eq!(next, 2);
        }
    );

Implementations§

Source§

impl<'r, T: Iterator> Peek<'r, T>

Source

pub const fn get(&self) -> Option<&T::Item>

Get a reference to the underlying peeked element.

Source

pub fn get_mut(&mut self) -> Option<&mut T::Item>

Get a mutable reference to the underlying peeked element.

Source

pub fn peek(&mut self) -> Option<&T::Item>

Get a reference to the element following what is currently peeked.

This is equivalent to calling peek_2 on the Peekable iterator directly.

If you just want a reference to what is currently peeked, see get.

§Example
let mut peek = iter.peek();
let value = peek.peek().copied();
let peek_2_val = iter.peek_2().copied();
 
assert_eq!(value, peek_2_val);
Source

pub fn peek_mut(&mut self) -> Option<&mut T::Item>

Get a mutable reference to the element following what is currently peeked.

This is equivalent to calling peek_2_mut on the Peekable iterator directly.

If you just want a mutable reference to what is currently peeked, see get_mut.

§Example
let mut iter = Peekable::new([1, 2, 3, 4].into_iter());
let mut peek = iter.peek();
peek.peek_mut().map(|val| *val *= 2);
 
assert_eq!(iter.peek_2(), Some(&4));
Source

pub fn consume(self) -> Option<T::Item>

Advance the iterator, taking ownership of the underlying peeked element.

This should be used similarly to next_if, otherwise it is simply a less efficient mode of calling next.

Under certain patterns, plus allow-unsafe being enabled, this will outperform next_if. See benches/next_if.rs for an example of this.

§Example
let mut iter = Peekable::new([1, 2, 3, 4].into_iter());
let peeked = iter.peek();
 
// in this scenario, it'd be best to use `next_if_eq`
let value = if peeked == Some(&1) {
    peeked.consume()
} else {
    None
};
 
assert_eq!(value, Some(1));
Source

pub fn drain_if<F>(self, predicate: F) -> DrainIf<'r, T>
where F: FnOnce(&T::Item) -> bool,

Drain the peeked elements if predicate returns true.

This is akin to next_if but over peek_2 rather than peek.

§Returns

If the second peek was Some and the predicate returned true this will return both peeked elements in order.

The first element returned is an option, despite it being atypical for Some to follow None in an iterator, it is not impossible as the underlying iterator may not be fused.

For more information on fused iterators see the FusedIterator marker trait.

§Example
let mut iter = Peekable::new([1, 2, 3, 4].into_iter());
let peeked = iter.peek();
 
// since we are peeked, drain_if is referencing the second element.
peeked.drain_if(|next| next == &2).map_or_else(
    |mut _peeked| unreachable!("The second element was two"),
    |(first, second)| {
        assert_eq!(first, Some(1));
        assert_eq!(second, 2);
    }
);
Source

pub fn drain_if_both<F>(self, predicate: F) -> DrainIfBoth<'r, T>
where F: FnOnce(&T::Item, &T::Item) -> bool,

Drain the peeked elements if predicate returns true.

This is similar to drain_if, the only distinction is both peeked elements are inspected.

§Returns

If the first and second peek were Some, and the predicate returned true, this will return both peeked elements in order.

§Example
let mut iter = Peekable::new([1, 2, 3, 4].into_iter());
let peeked = iter.peek();
 
// since we are peeked, drain_if is referencing the second element.
peeked.drain_if_both(|one, two| one == &1 && two == &2).map_or_else(
    |mut _peeked| unreachable!("The second element was two"),
    |first, second| {
        assert_eq!(first, 1);
        assert_eq!(second, 2);
    }
);
Source

pub fn is_both<F>(&mut self, predicate: F) -> bool
where F: FnOnce(&T::Item, &T::Item) -> bool,

Returns true if the next two peeked elements satisfy the predicate.

§Example
let mut iter = Peekable::new([1, 2, 3, 4].into_iter());
let mut peeked = iter.peek();
 
if !peeked.is_both(|a, b| a == &1 && b == &2) {
    unreachable!("The next two elements are 1 and 2");
}
 
// is both does not advance the iterator
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next(), Some(2));
assert_eq!(iter.next(), Some(3));
// ...
Source

pub fn take_next_if<F>(&mut self, predicate: F) -> Option<T::Item>
where F: FnOnce(&T::Item) -> bool,

Take only the second element, removing it from the iterator.

Unlike drain_if or next_if, this removes the second element if the predicate was satisfied, effectively modifying the order of the iterator. This is similar to if you were to have a Vec and called remove(1) behind some branch.

§Example
let mut iter = Peekable::new([1, 2, 3, 4].into_iter());
 
let mut peeked = iter.peek();
assert_eq!(
    peeked.take_next_if(|elem| elem == &2),
    Some(2)
);
 
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next(), Some(3)); // removed 2
assert_eq!(iter.next(), Some(4));

Trait Implementations§

Source§

impl<'r, T> Debug for Peek<'r, T>
where T: Iterator, <T as Iterator>::Item: Debug,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Writes “Peek(elem?)” to the provided Formatter.

Source§

impl<'r, T> PartialEq<Option<&<T as Iterator>::Item>> for Peek<'r, T>
where T: Iterator, <T as Iterator>::Item: PartialEq,

Source§

fn eq(&self, other: &Option<&T::Item>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.

Auto Trait Implementations§

§

impl<'r, T> Freeze for Peek<'r, T>

§

impl<'r, T> RefUnwindSafe for Peek<'r, T>

§

impl<'r, T> Send for Peek<'r, T>
where T: Send, <T as Iterator>::Item: Send,

§

impl<'r, T> Sync for Peek<'r, T>
where T: Sync, <T as Iterator>::Item: Sync,

§

impl<'r, T> Unpin for Peek<'r, T>

§

impl<'r, T> !UnwindSafe for Peek<'r, T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.