use super::size_hint; /// An iterator which iterates two other iterators simultaneously /// /// See [`.zip_eq()`](crate::Itertools::zip_eq) for more information. #[derive(Clone, Debug)] #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] pub struct ZipEq { a: I, b: J, } /// Iterate `i` and `j` in lock step. /// /// **Panics** if the iterators are not of the same length. /// /// [`IntoIterator`] enabled version of [`Itertools::zip_eq`](crate::Itertools::zip_eq). /// /// ``` /// use itertools::zip_eq; /// /// let data = [1, 2, 3, 4, 5]; /// for (a, b) in zip_eq(&data[..data.len() - 1], &data[1..]) { /// /* loop body */ /// } /// ``` pub fn zip_eq(i: I, j: J) -> ZipEq where I: IntoIterator, J: IntoIterator { ZipEq { a: i.into_iter(), b: j.into_iter(), } } impl Iterator for ZipEq where I: Iterator, J: Iterator { type Item = (I::Item, J::Item); fn next(&mut self) -> Option { match (self.a.next(), self.b.next()) { (None, None) => None, (Some(a), Some(b)) => Some((a, b)), (None, Some(_)) | (Some(_), None) => panic!("itertools: .zip_eq() reached end of one iterator before the other") } } fn size_hint(&self) -> (usize, Option) { size_hint::min(self.a.size_hint(), self.b.size_hint()) } } impl ExactSizeIterator for ZipEq where I: ExactSizeIterator, J: ExactSizeIterator {}