rust-itertools / itertools

Extra iterator adaptors, iterator methods, free functions, and macros.
https://docs.rs/itertools/
Apache License 2.0
2.72k stars 309 forks source link

Add a `PeekMap` iterator adaptor #668

Open tgross35 opened 1 year ago

tgross35 commented 1 year ago

Add an iterator that allows mapping with (next_item, Option(&peek_item). This is useful for parsers. Exact semantics may vary, but the goal is to get something like tuple_windows without needing to clone

100% credit to @talchas on Discord (I don't see that user here) for the implementation:

use std::iter::Peekable;
pub struct PeekMap<I: Iterator, F>(Peekable<I>, F);
pub fn peek_map<R, I: Iterator, F: FnMut(I::Item, Option<&I::Item>) -> R>(it: Peekable<I>, f: F) -> PeekMap<I, F> {
    PeekMap(it, f)
}
impl<R, I: Iterator, F: FnMut(I::Item, Option<&I::Item>) -> R> Iterator for PeekMap<I, F> {
    type Item = R;
    fn next(&mut self) -> Option<R> {
        let x = self.0.next()?;
        Some((self.1)(x, self.0.peek()))
    }
}
G-M0N3Y-2503 commented 2 months ago

Previously it looks like there was the desire to place this in std https://github.com/rust-itertools/itertools/pull/809 https://github.com/rust-lang/rust/pull/118474