date/
weekday.rs

1use std::fmt::Display;
2
3/// A representation of the day of the week.
4#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
5#[repr(u8)]
6pub enum Weekday {
7  Sunday = 0,
8  Monday = 1,
9  Tuesday = 2,
10  Wednesday = 3,
11  Thursday = 4,
12  Friday = 5,
13  Saturday = 6,
14}
15
16impl Display for Weekday {
17  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18    macro_rules! display {
19      ($($e:ident),*) => {
20        f.write_str(match self {
21          $(Self::$e => stringify!($e)),*
22        })
23      };
24    }
25    display!(Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday)
26  }
27}
28
29impl Weekday {
30  /// The three-letter abbreviation for this weekday.
31  pub(crate) fn abbv(&self) -> &'static str {
32    match self {
33      Self::Sunday => "Sun",
34      Self::Monday => "Mon",
35      Self::Tuesday => "Tue",
36      Self::Wednesday => "Wed",
37      Self::Thursday => "Thu",
38      Self::Friday => "Fri",
39      Self::Saturday => "Sat",
40    }
41  }
42}
43
44#[cfg(test)]
45mod tests {
46  use assert2::check;
47
48  use super::*;
49  use crate::interval::DateInterval;
50
51  #[test]
52  fn test_weekday() {
53    check!(date! { 1970-01-01 }.weekday() == Weekday::Thursday);
54
55    let mut date = date! { 2019-12-29 }; // A Sunday.
56    for weekday in [
57      Weekday::Sunday,
58      Weekday::Monday,
59      Weekday::Tuesday,
60      Weekday::Wednesday,
61      Weekday::Thursday,
62      Weekday::Friday,
63      Weekday::Saturday,
64    ]
65    .into_iter()
66    .cycle()
67    {
68      check!(date.weekday() == weekday, "Incorrect on: {:?}", date);
69      date += DateInterval::new(1);
70      if date.year() == 2022 && date.month() == 2 {
71        break;
72      }
73    }
74
75    // Also check some random dates in other centuries.
76    check!(date! { 1700-01-01 }.weekday() == Weekday::Friday);
77    check!(date! { 1800-01-01 }.weekday() == Weekday::Wednesday);
78    check!(date! { 1900-01-01 }.weekday() == Weekday::Monday);
79    check!(date! { 2000-01-01 }.weekday() == Weekday::Saturday);
80    check!(date! { 2100-01-01 }.weekday() == Weekday::Friday);
81    check!(date! { 2200-01-01 }.weekday() == Weekday::Wednesday);
82    check!(date! { 2300-01-01 }.weekday() == Weekday::Monday);
83    check!(date! { 2400-01-01 }.weekday() == Weekday::Saturday);
84    check!(date! { 2500-01-01 }.weekday() == Weekday::Friday);
85
86    // And some around now...
87    check!(date! { 2021-07-04 }.weekday() == Weekday::Sunday);
88    check!(date! { 2024-03-31 }.weekday() == Weekday::Sunday);
89    check!(date! { 2024-11-28 }.weekday() == Weekday::Thursday);
90  }
91
92  #[test]
93  fn test_display() {
94    for (weekday, weekday_str, weekday_abbv_str) in [
95      (Weekday::Sunday, "Sunday", "Sun"),
96      (Weekday::Monday, "Monday", "Mon"),
97      (Weekday::Tuesday, "Tuesday", "Tue"),
98      (Weekday::Wednesday, "Wednesday", "Wed"),
99      (Weekday::Thursday, "Thursday", "Thu"),
100      (Weekday::Friday, "Friday", "Fri"),
101      (Weekday::Saturday, "Saturday", "Sat"),
102    ] {
103      check!(weekday.to_string() == weekday_str);
104      check!(weekday.abbv() == weekday_abbv_str);
105    }
106  }
107}