#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct ZipEq<A, B> {
a: A,
b: B,
}
pub fn zip_eq<A, AIter, B, BIter, Error>(
a: A,
b: B,
err: Error,
) -> Result<ZipEq<A::IntoIter, B::IntoIter>, Error>
where
A: IntoIterator<IntoIter = AIter>,
AIter: ExactSizeIterator,
B: IntoIterator<IntoIter = BIter>,
BIter: ExactSizeIterator,
{
let a_iter = a.into_iter();
let b_iter = b.into_iter();
if a_iter.len() == b_iter.len() {
Ok(ZipEq {
a: a_iter,
b: b_iter,
})
} else {
Err(err)
}
}
impl<A, B> Iterator for ZipEq<A, B>
where
A: ExactSizeIterator, B: ExactSizeIterator,
{
type Item = (A::Item, B::Item);
fn next(&mut self) -> Option<Self::Item> {
match (self.a.next(), self.b.next()) {
(Some(a), Some(b)) => Some((a, b)),
(None, None) => None,
_ => unreachable!("The iterators must have the same length."),
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
debug_assert_eq!(self.a.size_hint(), self.b.size_hint());
self.a.size_hint()
}
}
impl<A, B> ExactSizeIterator for ZipEq<A, B>
where
A: ExactSizeIterator,
B: ExactSizeIterator,
{
}
#[cfg(test)]
mod tests {
use alloc::vec;
use alloc::vec::Vec;
use super::*;
#[test]
fn test_zip_eq_success() {
let a = [1, 2, 3];
let b = ['a', 'b', 'c'];
let zipped = zip_eq(a, b, "length mismatch").unwrap();
let result: Vec<_> = zipped.collect();
assert_eq!(result, vec![(1, 'a'), (2, 'b'), (3, 'c')]);
}
#[test]
fn test_zip_eq_length_mismatch() {
let a = [1, 2];
let b = ['x', 'y', 'z'];
match zip_eq(a, b, "oops") {
Err(e) => assert_eq!(e, "oops"),
Ok(_) => panic!("expected error due to mismatched lengths"),
}
}
#[test]
fn test_zip_eq_empty_iterators() {
let a: [i32; 0] = [];
let b: [char; 0] = [];
let mut zipped = zip_eq(a, b, "mismatch").unwrap();
assert!(zipped.next().is_none());
}
#[test]
fn test_zip_eq_size_hint() {
let a = [10, 20];
let b = [100, 200];
let zipped = zip_eq(a, b, "bad").unwrap();
assert_eq!(zipped.size_hint(), (2, Some(2)));
}
#[test]
fn test_zip_eq_unreachable_case() {
let a = [1, 2];
let b = [3, 4];
let mut zipped = zip_eq(a, b, "fail").unwrap();
assert_eq!(zipped.next(), Some((1, 3)));
assert_eq!(zipped.next(), Some((2, 4)));
assert_eq!(zipped.next(), None);
}
}