shiftnanigans/incrementer/
limited_incrementer.rs

1use 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        //pretty_env_logger::try_init();
73    }
74
75    #[rstest]
76    fn limit_one_with_possible_one() {
77        init();
78
79        // create an ShifterIncrementer with an IndexShifter with one possible value
80    }
81}