Subset) -> ZipIter<'a> { ZipIter { a_segs: self.segments.as_slice(), b_segs: other.segments.as_slice(), a_i: 0, b_i: 0, a_consumed: 0, b_consumed: 0, consumed: 0, } } /// See `Subset::zip` pub struct ZipIter<'a> { a_segs: &'a [Segment], b_segs: &'a [Segment], a_i: usize, b_i: usize, a_consumed: usize, b_consumed: usize, pub consumed: usize, } /// See `Subset::zip` #[derive(Clone, Debug)] pub struct ZipSegment { len: usize, a_count: usize, b_count: usize, } impl<'a> Iterator for ZipIter<'a> { type Item = ZipSegment; /// Consume as far as possible from `self.consumed` until reaching a /// segment boundary in either `Subset`, and return the resulting /// `ZipSegment`. Will panic if it reaches the end of one `Subset` before /// the other, that is when they have different total length. fn next(&mut self) -> Option<ZipSegment> { match (self.a_segs.get(self.a_i), self.b_segs.get(self.b_i)) { (None, None) => None, (None, Some(_)) | (Some(_), None) => panic!("can't zip Subsets of different base lengths."), (Some(&Segment {len: a_len, count: a_count}), Some(&Segment {len: b_len, count: b_count})) => { let len = if a_len + self.a_consumed == b_len + self.b_consumed { self.a_consumed += a_len; self.a_i += 1; self.b_consumed += b_len; self.b_i += 1; self.a_consumed - self.consumed } else if a_len + self.a_consumed < b_len + self.b_consumed { self.a_consumed += a_len; self.a_i += 1; self.a_consumed - self.consumed } else { self.b_consumed += b_len; self.b_i += 1; self.b_consumed - self.consumed }; self.consumed += len; Some(ZipSegment {len, a_count, b_count}) } } } }