shiftnanigans/incrementer/
limited_incrementer.rs1use crate::IndexedElement;
2use super::Incrementer;
3
4pub struct LimitedIncrementer<T> {
5 incrementer: Box<dyn Incrementer<T = T>>,
6 length: usize,
7 current_index: Option<usize>,
8 is_completed: bool
9}
10
11impl<T> LimitedIncrementer<T> {
12 pub fn new(incrementer: Box<dyn Incrementer<T = T>>, length: usize) -> Self {
13 LimitedIncrementer {
14 incrementer: incrementer,
15 length: length,
16 current_index: None,
17 is_completed: length == 0
18 }
19 }
20}
21
22impl<T> Incrementer for LimitedIncrementer<T> {
23 type T = T;
24
25 fn try_increment(&mut self) -> bool {
26 if self.is_completed {
27 return false;
28 }
29 if let Some(current_index) = self.current_index {
30 let next_index = current_index + 1;
31 if next_index == self.length {
32 self.is_completed = true;
33 return false;
34 }
35 self.current_index = Some(next_index);
36 }
37 else {
38 self.current_index = Some(0);
39 }
40 return self.incrementer.try_increment();
41 }
42 fn get(&self) -> Vec<IndexedElement<Self::T>> {
43 return self.incrementer.get();
44 }
45 fn reset(&mut self) {
46 self.incrementer.reset();
47 self.is_completed = self.length == 0;
48 self.current_index = None;
49 }
50 fn randomize(&mut self) {
51 self.incrementer.randomize();
52 }
53}
54
55impl<T> Iterator for LimitedIncrementer<T> {
56 type Item = Vec<IndexedElement<T>>;
57
58 fn next(&mut self) -> Option<<Self as Iterator>::Item> {
59 if self.try_increment() {
60 return Some(self.get());
61 }
62 return None;
63 }
64}
65
66#[cfg(test)]
67mod limited_incrementer_tests {
68 use rstest::rstest;
69
70 fn init() {
71 std::env::set_var("RUST_LOG", "trace");
72 }
74
75 #[rstest]
76 fn limit_one_with_possible_one() {
77 init();
78
79 }
81}