1use core::iter::Iterator;
2
3use crate::Weekday;
4
5#[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#[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 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 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}