Skip to main content

weekday/
iter.rs

1use core::iter::Iterator;
2
3use crate::Weekday;
4
5//
6#[derive(Default, Debug, Clone, PartialEq)]
7pub struct WeekdayIterator {
8    finished: bool,
9    curr_front: Option<Weekday>,
10    curr_back: Option<Weekday>,
11}
12impl WeekdayIterator {
13    pub fn new() -> Self {
14        Self::default()
15    }
16}
17impl Iterator for WeekdayIterator {
18    type Item = Weekday;
19
20    fn next(&mut self) -> Option<Self::Item> {
21        if self.finished {
22            return None;
23        }
24        let next = if let Some(w) = &self.curr_front {
25            w.next()
26        } else {
27            Some(Weekday::first())
28        };
29        if next == self.curr_back {
30            self.finished = true;
31            return None;
32        }
33        self.curr_front = next.to_owned();
34        next
35    }
36}
37impl DoubleEndedIterator for WeekdayIterator {
38    fn next_back(&mut self) -> Option<Self::Item> {
39        if self.finished {
40            return None;
41        }
42        let prev = if let Some(w) = &self.curr_back {
43            w.prev()
44        } else {
45            Some(Weekday::last())
46        };
47        if prev == self.curr_front {
48            self.finished = true;
49            return None;
50        }
51        self.curr_back = prev.to_owned();
52        prev
53    }
54}
55
56//
57#[derive(Default, Debug, Clone, PartialEq)]
58pub struct WeekdayFromSundayIterator {
59    finished: bool,
60    curr_front: Option<Weekday>,
61    curr_back: Option<Weekday>,
62}
63impl WeekdayFromSundayIterator {
64    pub fn new() -> Self {
65        Self::default()
66    }
67}
68impl Iterator for WeekdayFromSundayIterator {
69    type Item = Weekday;
70
71    fn next(&mut self) -> Option<Self::Item> {
72        if self.finished {
73            return None;
74        }
75        let next = if let Some(w) = &self.curr_front {
76            w.next_from_sunday()
77        } else {
78            Some(Weekday::first_from_sunday())
79        };
80        if next == self.curr_back {
81            self.finished = true;
82            return None;
83        }
84        self.curr_front = next.to_owned();
85        next
86    }
87}
88impl DoubleEndedIterator for WeekdayFromSundayIterator {
89    fn next_back(&mut self) -> Option<Self::Item> {
90        if self.finished {
91            return None;
92        }
93        let prev = if let Some(w) = &self.curr_back {
94            w.prev_from_sunday()
95        } else {
96            Some(Weekday::last_from_sunday())
97        };
98        if prev == self.curr_front {
99            self.finished = true;
100            return None;
101        }
102        self.curr_back = prev.to_owned();
103        prev
104    }
105}
106
107#[cfg(test)]
108mod tests {
109    use super::*;
110
111    #[test]
112    fn test_weekday_iterator() {
113        assert_eq!(
114            WeekdayIterator::new().collect::<Vec<_>>(),
115            vec![
116                Weekday::Mon,
117                Weekday::Tue,
118                Weekday::Wed,
119                Weekday::Thu,
120                Weekday::Fri,
121                Weekday::Sat,
122                Weekday::Sun,
123            ]
124        );
125
126        assert_eq!(
127            WeekdayIterator::new().rev().collect::<Vec<_>>(),
128            vec![
129                Weekday::Sun,
130                Weekday::Sat,
131                Weekday::Fri,
132                Weekday::Thu,
133                Weekday::Wed,
134                Weekday::Tue,
135                Weekday::Mon,
136            ]
137        );
138
139        // https://doc.rust-lang.org/std/iter/trait.DoubleEndedIterator.html#examples
140        let mut iter = WeekdayIterator::new();
141        assert_eq!(iter.next(), Some(Weekday::Mon));
142        assert_eq!(iter.next_back(), Some(Weekday::Sun));
143        assert_eq!(iter.next_back(), Some(Weekday::Sat));
144        assert_eq!(iter.next(), Some(Weekday::Tue));
145        assert_eq!(iter.next(), Some(Weekday::Wed));
146        assert_eq!(iter.next(), Some(Weekday::Thu));
147        assert_eq!(iter.next(), Some(Weekday::Fri));
148        assert_eq!(iter.next(), None);
149        assert_eq!(iter.next_back(), None);
150        assert!(iter.finished);
151        assert_eq!(iter.curr_front, Some(Weekday::Fri));
152        assert_eq!(iter.curr_back, Some(Weekday::Sat));
153    }
154
155    #[test]
156    fn test_weekday_from_sunday_iterator() {
157        assert_eq!(
158            WeekdayFromSundayIterator::new().collect::<Vec<_>>(),
159            vec![
160                Weekday::Sun,
161                Weekday::Mon,
162                Weekday::Tue,
163                Weekday::Wed,
164                Weekday::Thu,
165                Weekday::Fri,
166                Weekday::Sat,
167            ]
168        );
169
170        assert_eq!(
171            WeekdayFromSundayIterator::new().rev().collect::<Vec<_>>(),
172            vec![
173                Weekday::Sat,
174                Weekday::Fri,
175                Weekday::Thu,
176                Weekday::Wed,
177                Weekday::Tue,
178                Weekday::Mon,
179                Weekday::Sun,
180            ]
181        );
182
183        // https://doc.rust-lang.org/std/iter/trait.DoubleEndedIterator.html#examples
184        let mut iter = WeekdayFromSundayIterator::new();
185        assert_eq!(iter.next(), Some(Weekday::Sun));
186        assert_eq!(iter.next_back(), Some(Weekday::Sat));
187        assert_eq!(iter.next_back(), Some(Weekday::Fri));
188        assert_eq!(iter.next(), Some(Weekday::Mon));
189        assert_eq!(iter.next(), Some(Weekday::Tue));
190        assert_eq!(iter.next(), Some(Weekday::Wed));
191        assert_eq!(iter.next(), Some(Weekday::Thu));
192        assert_eq!(iter.next(), None);
193        assert_eq!(iter.next_back(), None);
194        assert!(iter.finished);
195        assert_eq!(iter.curr_front, Some(Weekday::Thu));
196        assert_eq!(iter.curr_back, Some(Weekday::Fri));
197    }
198}