non_empty_iter/
zip.rs

1//! Zipping two non-empty iterators together.
2
3use core::iter;
4
5use crate::non_empty::{IntoNonEmptyIterator, NonEmptyIterator};
6
7/// Converts the given arguments to non-empty iterators and zips them.
8///
9/// See the documentation of [`NonEmptyIterator::zip`] for more.
10pub fn zip<I: IntoNonEmptyIterator, J: IntoNonEmptyIterator>(
11    first: I,
12    second: J,
13) -> Zip<I::IntoNonEmptyIter, J::IntoNonEmptyIter> {
14    Zip::new(first.into_non_empty_iter(), second.into_non_empty_iter())
15}
16
17/// Represents non-empty iterators that iterate over two other non-empty iterators simultaneously.
18///
19/// This struct is created by the [`zip`] function and [`NonEmptyIterator::zip`] method.
20/// See their documentation for more.
21#[derive(Debug, Clone)]
22#[must_use = "non-empty iterators are lazy and do nothing unless consumed"]
23pub struct Zip<I: NonEmptyIterator, J: NonEmptyIterator> {
24    first: I,
25    second: J,
26}
27
28impl<I: NonEmptyIterator, J: NonEmptyIterator> Zip<I, J> {
29    /// Constructs [`Self`].
30    pub const fn new(first: I, second: J) -> Self {
31        Self { first, second }
32    }
33}
34
35impl<I: NonEmptyIterator, J: NonEmptyIterator> IntoIterator for Zip<I, J> {
36    type Item = (I::Item, J::Item);
37
38    type IntoIter = iter::Zip<I::IntoIter, J::IntoIter>;
39
40    fn into_iter(self) -> Self::IntoIter {
41        iter::zip(self.first, self.second)
42    }
43}
44
45unsafe impl<I: NonEmptyIterator, J: NonEmptyIterator> NonEmptyIterator for Zip<I, J> {}