1use std::cmp::Ordering::{Equal, Less};
3
4pub struct Combinations<'a, T> {
18 inner: &'a [Option<T>],
19 idx1: usize,
20 idx2: usize,
21}
22
23impl<'a, T> Combinations<'a, T> {
24 pub(crate) fn new(inner: &'a [Option<T>]) -> Self {
26 Self {
27 inner,
28 idx1: 0,
29 idx2: 1,
30 }
31 }
32
33 pub(crate) fn set_to_last(&mut self) {
34 self.idx1 = self.inner.len() - 1;
35 self.idx2 = 0;
36 }
37}
38
39impl<'a, T> Iterator for Combinations<'a, T> {
40 type Item = (&'a T, &'a T);
41 fn next(&mut self) -> Option<Self::Item> {
42 match (
43 self.idx1 < self.inner.len(),
44 self.idx2.cmp(&self.inner.len()),
45 ) {
46 (true, Less) => {
47 self.idx2 += 1;
48 if self.inner[self.idx1].is_none() {
49 return self.next();
50 }
51 if self.inner[self.idx2 - 1].is_none() {
52 return self.next();
53 }
54 Some((
55 self.inner[self.idx1]
56 .as_ref()
57 .expect("`None` values are skipped"),
58 self.inner[self.idx2 - 1]
59 .as_ref()
60 .expect("`None` values are skipped"),
61 ))
62 }
63 (true, Equal) => {
64 self.idx1 += 1;
65 self.idx2 = self.idx1 + 1;
66 self.next()
67 }
68 _ => None,
69 }
70 }
71}
72
73#[cfg(test)]
74mod test {
75 use super::*;
76
77 #[test]
78 fn combinations() {
79 let a = vec![Some(1), Some(2), Some(3), Some(4)];
80 let mut c = Combinations::new(&a);
81 assert_eq!(c.next(), Some((&1, &2)));
82 assert_eq!(c.next(), Some((&1, &3)));
83 assert_eq!(c.next(), Some((&1, &4)));
84 assert_eq!(c.next(), Some((&2, &3)));
85 assert_eq!(c.next(), Some((&2, &4)));
86 assert_eq!(c.next(), Some((&3, &4)));
87 assert_eq!(c.next(), None);
88 }
89
90 #[test]
91 fn combinations_empty() {
92 let a: Vec<Option<usize>> = vec![];
93 let mut c = Combinations::new(&a);
94 assert_eq!(c.next(), None);
95 }
96
97 #[test]
98 fn combinations_single() {
99 let a = vec![Some(1)];
100 let mut c = Combinations::new(&a);
101 assert_eq!(c.next(), None);
102 }
103
104 #[test]
105 fn combinations_two() {
106 let a = vec![Some(1), Some(2)];
107 let mut c = Combinations::new(&a);
108 assert_eq!(c.next(), Some((&1, &2)));
109 assert_eq!(c.next(), None);
110 }
111
112 #[test]
113 fn last_row() {
114 let a = vec![Some(1), Some(2), Some(3), Some(4)];
115 let mut c = Combinations::new(&a);
116 c.set_to_last();
117 assert_eq!(c.next(), Some((&4, &1)));
118 assert_eq!(c.next(), Some((&4, &2)));
119 assert_eq!(c.next(), Some((&4, &3)));
120 assert_eq!(c.next(), Some((&4, &4)));
121 assert_eq!(c.next(), None);
122 }
123
124 #[test]
125 fn combinations_with_none() {
126 let a = vec![Some(1), Some(2), None, Some(4)];
127 let mut c = Combinations::new(&a);
128 assert_eq!(c.next(), Some((&1, &2)));
129 assert_eq!(c.next(), Some((&1, &4)));
130 assert_eq!(c.next(), Some((&2, &4)));
131 assert_eq!(c.next(), None);
132 }
133}