1//! Days of the week.
2
3use core::fmt::{self, Display};
4use core::str::FromStr;
5
6use Weekday::*;
7
8use crate::error;
9
10/// Days of the week.
11///
12/// As order is dependent on context (Sunday could be either two days after or five days before
13/// Friday), this type does not implement `PartialOrd` or `Ord`.
14#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
15pub enum Weekday {
16 #[allow(clippy::missing_docs_in_private_items)]
17 Monday,
18 #[allow(clippy::missing_docs_in_private_items)]
19 Tuesday,
20 #[allow(clippy::missing_docs_in_private_items)]
21 Wednesday,
22 #[allow(clippy::missing_docs_in_private_items)]
23 Thursday,
24 #[allow(clippy::missing_docs_in_private_items)]
25 Friday,
26 #[allow(clippy::missing_docs_in_private_items)]
27 Saturday,
28 #[allow(clippy::missing_docs_in_private_items)]
29 Sunday,
30}
31
32impl Weekday {
33 /// Get the previous weekday.
34 ///
35 /// ```rust
36 /// # use time::Weekday;
37 /// assert_eq!(Weekday::Tuesday.previous(), Weekday::Monday);
38 /// ```
39 pub const fn previous(self) -> Self {
40 match self {
41 Monday => Sunday,
42 Tuesday => Monday,
43 Wednesday => Tuesday,
44 Thursday => Wednesday,
45 Friday => Thursday,
46 Saturday => Friday,
47 Sunday => Saturday,
48 }
49 }
50
51 /// Get the next weekday.
52 ///
53 /// ```rust
54 /// # use time::Weekday;
55 /// assert_eq!(Weekday::Monday.next(), Weekday::Tuesday);
56 /// ```
57 pub const fn next(self) -> Self {
58 match self {
59 Monday => Tuesday,
60 Tuesday => Wednesday,
61 Wednesday => Thursday,
62 Thursday => Friday,
63 Friday => Saturday,
64 Saturday => Sunday,
65 Sunday => Monday,
66 }
67 }
68
69 /// Get n-th next day.
70 ///
71 /// ```rust
72 /// # use time::Weekday;
73 /// assert_eq!(Weekday::Monday.nth_next(1), Weekday::Tuesday);
74 /// assert_eq!(Weekday::Sunday.nth_next(10), Weekday::Wednesday);
75 /// ```
76 pub const fn nth_next(self, n: u8) -> Self {
77 match (self.number_days_from_monday() + n % 7) % 7 {
78 0 => Monday,
79 1 => Tuesday,
80 2 => Wednesday,
81 3 => Thursday,
82 4 => Friday,
83 5 => Saturday,
84 val => {
85 debug_assert!(val == 6);
86 Sunday
87 }
88 }
89 }
90
91 /// Get the one-indexed number of days from Monday.
92 ///
93 /// ```rust
94 /// # use time::Weekday;
95 /// assert_eq!(Weekday::Monday.number_from_monday(), 1);
96 /// ```
97 #[doc(alias = "iso_weekday_number")]
98 pub const fn number_from_monday(self) -> u8 {
99 self.number_days_from_monday() + 1
100 }
101
102 /// Get the one-indexed number of days from Sunday.
103 ///
104 /// ```rust
105 /// # use time::Weekday;
106 /// assert_eq!(Weekday::Monday.number_from_sunday(), 2);
107 /// ```
108 pub const fn number_from_sunday(self) -> u8 {
109 self.number_days_from_sunday() + 1
110 }
111
112 /// Get the zero-indexed number of days from Monday.
113 ///
114 /// ```rust
115 /// # use time::Weekday;
116 /// assert_eq!(Weekday::Monday.number_days_from_monday(), 0);
117 /// ```
118 pub const fn number_days_from_monday(self) -> u8 {
119 self as _
120 }
121
122 /// Get the zero-indexed number of days from Sunday.
123 ///
124 /// ```rust
125 /// # use time::Weekday;
126 /// assert_eq!(Weekday::Monday.number_days_from_sunday(), 1);
127 /// ```
128 pub const fn number_days_from_sunday(self) -> u8 {
129 match self {
130 Monday => 1,
131 Tuesday => 2,
132 Wednesday => 3,
133 Thursday => 4,
134 Friday => 5,
135 Saturday => 6,
136 Sunday => 0,
137 }
138 }
139}
140
141impl Display for Weekday {
142 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
143 f.write_str(data:match self {
144 Monday => "Monday",
145 Tuesday => "Tuesday",
146 Wednesday => "Wednesday",
147 Thursday => "Thursday",
148 Friday => "Friday",
149 Saturday => "Saturday",
150 Sunday => "Sunday",
151 })
152 }
153}
154
155impl FromStr for Weekday {
156 type Err = error::InvalidVariant;
157
158 fn from_str(s: &str) -> Result<Self, Self::Err> {
159 match s {
160 "Monday" => Ok(Monday),
161 "Tuesday" => Ok(Tuesday),
162 "Wednesday" => Ok(Wednesday),
163 "Thursday" => Ok(Thursday),
164 "Friday" => Ok(Friday),
165 "Saturday" => Ok(Saturday),
166 "Sunday" => Ok(Sunday),
167 _ => Err(error::InvalidVariant),
168 }
169 }
170}
171