use alloc::vec::Vec;
pub(crate) fn mate_to_pairs<I: Copy>(mate: &[Option<usize>], indices: &[I]) -> Vec<(I, I)> {
let mut pairs = Vec::with_capacity(mate.len() / 2);
for (i, slot) in mate.iter().enumerate() {
if let Some(j) = *slot
&& i < j
{
pairs.push((indices[i], indices[j]));
}
}
pairs
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_empty_mate() {
let pairs: Vec<(usize, usize)> = mate_to_pairs(&[], &[] as &[usize]);
assert_eq!(pairs, [] as [(usize, usize); 0]);
}
#[test]
fn test_all_none() {
let mate = [None, None, None, None];
let indices = [0usize, 1, 2, 3];
let pairs = mate_to_pairs(&mate, &indices);
assert_eq!(pairs, [] as [(usize, usize); 0]);
}
#[test]
fn test_single_pair() {
let mate = [Some(1), Some(0)];
let indices = [0usize, 1];
let pairs = mate_to_pairs(&mate, &indices);
assert_eq!(pairs, vec![(0, 1)]);
}
#[test]
fn test_two_pairs() {
let mate = [Some(1), Some(0), Some(3), Some(2)];
let indices = [0usize, 1, 2, 3];
let pairs = mate_to_pairs(&mate, &indices);
assert_eq!(pairs, vec![(0, 1), (2, 3)]);
}
#[test]
fn test_mixed_matched_and_exposed() {
let mate = [None, Some(2), Some(1), None, Some(5), Some(4)];
let indices = [0usize, 1, 2, 3, 4, 5];
let pairs = mate_to_pairs(&mate, &indices);
assert_eq!(pairs, vec![(1, 2), (4, 5)]);
}
#[test]
fn test_non_identity_indices() {
let mate = [Some(1), Some(0), Some(3), Some(2)];
let indices = [10u32, 20, 30, 40];
let pairs = mate_to_pairs(&mate, &indices);
assert_eq!(pairs, vec![(10, 20), (30, 40)]);
}
#[test]
fn test_odd_count_one_exposed() {
let mate = [Some(2), None, Some(0)];
let indices = [0usize, 1, 2];
let pairs = mate_to_pairs(&mate, &indices);
assert_eq!(pairs, vec![(0, 2)]);
}
}