date_time_matrix/
weekday_and_hour.rs1use core::iter::Iterator;
2
3#[cfg(feature = "with-chrono")]
4use chrono::{DateTime, NaiveDateTime, TimeZone};
5use hour::Hour;
6use weekday::Weekday;
7
8#[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Copy, Clone)]
10pub struct WeekdayAndHour(pub Weekday, pub Hour);
11
12#[cfg(feature = "with-chrono")]
13impl From<NaiveDateTime> for WeekdayAndHour {
14 fn from(dt: NaiveDateTime) -> Self {
15 Self(Weekday::from(dt), Hour::from(dt))
16 }
17}
18
19#[cfg(feature = "with-chrono")]
20impl<Tz: TimeZone> From<DateTime<Tz>> for WeekdayAndHour {
21 fn from(dt: DateTime<Tz>) -> Self {
22 Self(Weekday::from(dt.clone()), Hour::from(dt))
23 }
24}
25
26#[derive(Debug, Clone, Default)]
28pub struct WeekdayAndHourIterator {
29 curr: Option<WeekdayAndHour>,
30}
31
32impl WeekdayAndHourIterator {
33 pub fn new() -> Self {
34 Self::default()
35 }
36}
37
38impl Iterator for WeekdayAndHourIterator {
39 type Item = WeekdayAndHour;
40
41 fn next(&mut self) -> Option<Self::Item> {
42 let new = match &self.curr {
43 Some(v) => {
44 let WeekdayAndHour(w, h) = v;
45 match h.next() {
46 Some(h) => Some(WeekdayAndHour(w.to_owned(), h)),
47 None => w.next().map(|w| WeekdayAndHour(w, Hour::C0)),
48 }
49 }
50 None => Some(WeekdayAndHour(Weekday::first(), Hour::C0)),
51 };
52 self.curr = new.to_owned();
53 new
54 }
55}
56
57#[derive(Debug, Clone, Default)]
59pub struct WeekdayFromSundayAndHourIterator {
60 curr: Option<WeekdayAndHour>,
61}
62
63impl WeekdayFromSundayAndHourIterator {
64 pub fn new() -> Self {
65 Self::default()
66 }
67}
68
69impl Iterator for WeekdayFromSundayAndHourIterator {
70 type Item = WeekdayAndHour;
71
72 fn next(&mut self) -> Option<Self::Item> {
73 let new = match &self.curr {
74 Some(v) => {
75 let WeekdayAndHour(w, h) = v;
76 match h.next() {
77 Some(h) => Some(WeekdayAndHour(w.to_owned(), h)),
78 None => w.next_from_sunday().map(|w| WeekdayAndHour(w, Hour::C0)),
79 }
80 }
81 None => Some(WeekdayAndHour(Weekday::first_from_sunday(), Hour::C0)),
82 };
83 self.curr = new.to_owned();
84 new
85 }
86}
87
88#[cfg(test)]
89mod tests {
90 use super::*;
91
92 #[cfg(feature = "with-chrono")]
93 #[test]
94 fn test_from_chrono() {
95 use chrono::Utc;
96
97 assert_eq!(
98 WeekdayAndHour::from("2021-08-01T00:00:00".parse::<NaiveDateTime>().unwrap()),
99 WeekdayAndHour(Weekday::Sun, Hour::C0)
100 );
101
102 assert_eq!(
103 WeekdayAndHour::from("2021-08-01T00:00:00Z".parse::<DateTime<Utc>>().unwrap()),
104 WeekdayAndHour(Weekday::Sun, Hour::C0)
105 );
106 }
107
108 #[test]
109 fn test_iter() {
110 assert_eq!(WeekdayAndHourIterator::new().count(), 7 * 24);
111
112 assert_eq!(
113 WeekdayAndHourIterator::new().next(),
114 Some(WeekdayAndHour(Weekday::Mon, Hour::C0))
115 );
116 }
117
118 #[test]
119 fn test_from_sunday_iter() {
120 assert_eq!(WeekdayFromSundayAndHourIterator::new().count(), 7 * 24);
121
122 assert_eq!(
123 WeekdayFromSundayAndHourIterator::new().next(),
124 Some(WeekdayAndHour(Weekday::Sun, Hour::C0))
125 );
126 }
127}