rust-itertools / itertools

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

Merge `MultiPeek` and `PeekNth` #933

Open Philippe-Cholet opened 5 months ago

Philippe-Cholet commented 5 months ago

Those two adaptors are quite similar, except one handles an additional index. While specializing nth/last/count for them, I nearly wrote the same code. Before going further, I think they should be aliases of a more general struct.

Merge those would reduce duplication and additionally provide more methods for MultiPeek for "free".

I note that most of methods' documentation would be merged. We would need to be "careful" on this.

Draft

#[derive(Debug, Clone)]
/*kept private*/ struct MultiPeekGeneral<I: Iterator, Idx> {
    iter: Fuse<I>,
    buf: VecDeque<I::Item>,
    index: Idx,
}
pub type MultiPeek<I> = MultiPeekGeneral<I, usize>;
pub type PeekNth<I> = MultiPeekGeneral<I, ()>;

/*kept private*/ trait PeekIndex { ... } // fn reset_index probably. Maybe more.
impl PeekIndex for () { ... }
impl PeekIndex for usize { ... }

impl<I: Iterator, Idx: PeekIndex> MultiPeekGeneral<I, Idx> {
    // public functions: peek peek_mut peek_nth peek_nth_mut next_if next_if_eq nth_if nth_if_eq
}
impl<I: Iterator> MultiPeek<I> { // not for PeekNth
    // public functions: reset_peek
}

impl<I: Iterator, Idx> Iterator for MultiPeekGeneral<I, Idx> { ... }
impl<I: ExactSizeIterator, Idx> ExactSizeIterator for MultiPeekGeneral<I, Idx> {}

impl<I: Iterator, Idx> PeekingNext for MultiPeekGeneral<I, Idx> { ... }
Owen-CH-Leung commented 5 months ago

I'll take a look and create a PR soon