pact_models 1.0.4

Pact-Rust support library that provides the core models for dealing with Pact files
Documentation

pub(crate) struct CartesianProductIterator<'a, I1, I2> {
  v1: &'a [I1],
  v2: &'a [I2],
  v1_idx: usize,
  v2_idx: usize
}

impl <'a, I1, I2> CartesianProductIterator<'a, I1, I2> {
  pub fn new(v1: &'a [I1], v2: &'a [I2]) -> Self {
    CartesianProductIterator { v1, v2, v1_idx: 0, v2_idx: 0 }
  }
}

impl <'a, I1: 'a, I2> Iterator for CartesianProductIterator<'a, I1, I2> {
  type Item = (&'a I1, &'a I2);

  fn next(&mut self) -> Option<Self::Item> {
    if self.v1.is_empty() || self.v2.is_empty() || self.v1_idx == self.v1.len() &&
      self.v2_idx == self.v2.len() {
      None
    } else if self.v2_idx == self.v2.len() {
      self.v2_idx = 1;
      self.v1_idx += 1;
      if self.v1_idx == self.v1.len() {
        None
      } else {
        Some((self.v1.get(self.v1_idx).unwrap(), self.v2.get(self.v2_idx - 1).unwrap()))
      }
    } else {
      self.v2_idx += 1;
      Some((self.v1.get(self.v1_idx).unwrap(), self.v2.get(self.v2_idx - 1).unwrap()))
    }
  }
}

#[cfg(test)]
mod tests {
  use expectest::prelude::*;
  use super::CartesianProductIterator;

  #[test]
  fn cartesian_product_iterator_empty_array_tests() {
    expect!(CartesianProductIterator::new(&Vec::<usize>::new(), &Vec::<usize>::new()).next()).to(be_none());
    expect!(CartesianProductIterator::new(&vec![1], &Vec::<usize>::new()).next()).to(be_none());
    expect!(CartesianProductIterator::new(&Vec::<usize>::new(), &vec![1]).next()).to(be_none());
  }

  #[test]
  fn cartesian_product_iterator_tests() {
    let vec1 = vec![1];
    let vec2 = vec![2];
    let mut i1 = CartesianProductIterator::new(&vec1, &vec2);
    expect!(i1.next()).to(be_some().value((&1, &2)));
    expect!(i1.next()).to(be_none());

    let vec3 = vec![1, 2];
    let mut i2 = CartesianProductIterator::new(&vec3, &vec2);
    expect!(i2.next()).to(be_some().value((&1, &2)));
    expect!(i2.next()).to(be_some().value((&2, &2)));
    expect!(i2.next()).to(be_none());

    let mut i3 = CartesianProductIterator::new(&vec1, &vec3);
    expect!(i3.next()).to(be_some().value((&1, &1)));
    expect!(i3.next()).to(be_some().value((&1, &2)));
    expect!(i3.next()).to(be_none());

    let vec4 = vec![2, 3];
    let mut i4 = CartesianProductIterator::new(&vec3, &vec4);
    expect!(i4.next()).to(be_some().value((&1, &2)));
    expect!(i4.next()).to(be_some().value((&1, &3)));
    expect!(i4.next()).to(be_some().value((&2, &2)));
    expect!(i4.next()).to(be_some().value((&2, &3)));
    expect!(i4.next()).to(be_none());
  }
}