1use core::fmt;
4use core::str::FromStr;
5
6use powerfmt::smart_display::{FormatterOptions, Metadata, SmartDisplay};
7
8use self::Weekday::*;
9use crate::error;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
16pub enum Weekday {
17 #[allow(missing_docs)]
18 Monday,
19 #[allow(missing_docs)]
20 Tuesday,
21 #[allow(missing_docs)]
22 Wednesday,
23 #[allow(missing_docs)]
24 Thursday,
25 #[allow(missing_docs)]
26 Friday,
27 #[allow(missing_docs)]
28 Saturday,
29 #[allow(missing_docs)]
30 Sunday,
31}
32
33impl Weekday {
34 pub const fn previous(self) -> Self {
41 match self {
42 Monday => Sunday,
43 Tuesday => Monday,
44 Wednesday => Tuesday,
45 Thursday => Wednesday,
46 Friday => Thursday,
47 Saturday => Friday,
48 Sunday => Saturday,
49 }
50 }
51
52 pub const fn next(self) -> Self {
59 match self {
60 Monday => Tuesday,
61 Tuesday => Wednesday,
62 Wednesday => Thursday,
63 Thursday => Friday,
64 Friday => Saturday,
65 Saturday => Sunday,
66 Sunday => Monday,
67 }
68 }
69
70 pub const fn nth_next(self, n: u8) -> Self {
78 match (self.number_days_from_monday() + n % 7) % 7 {
79 0 => Monday,
80 1 => Tuesday,
81 2 => Wednesday,
82 3 => Thursday,
83 4 => Friday,
84 5 => Saturday,
85 val => {
86 debug_assert!(val == 6);
87 Sunday
88 }
89 }
90 }
91
92 pub const fn nth_prev(self, n: u8) -> Self {
100 match self.number_days_from_monday() as i8 - (n % 7) as i8 {
101 1 | -6 => Tuesday,
102 2 | -5 => Wednesday,
103 3 | -4 => Thursday,
104 4 | -3 => Friday,
105 5 | -2 => Saturday,
106 6 | -1 => Sunday,
107 val => {
108 debug_assert!(val == 0);
109 Monday
110 }
111 }
112 }
113
114 #[doc(alias = "iso_weekday_number")]
121 pub const fn number_from_monday(self) -> u8 {
122 self.number_days_from_monday() + 1
123 }
124
125 pub const fn number_from_sunday(self) -> u8 {
132 self.number_days_from_sunday() + 1
133 }
134
135 pub const fn number_days_from_monday(self) -> u8 {
142 self as _
143 }
144
145 pub const fn number_days_from_sunday(self) -> u8 {
152 match self {
153 Monday => 1,
154 Tuesday => 2,
155 Wednesday => 3,
156 Thursday => 4,
157 Friday => 5,
158 Saturday => 6,
159 Sunday => 0,
160 }
161 }
162}
163
164mod private {
165 #[non_exhaustive]
166 #[derive(Debug, Clone, Copy)]
167 pub struct WeekdayMetadata;
168}
169use private::WeekdayMetadata;
170
171impl SmartDisplay for Weekday {
172 type Metadata = WeekdayMetadata;
173
174 fn metadata(&self, _: FormatterOptions) -> Metadata<'_, Self> {
175 match self {
176 Monday => Metadata::new(6, self, WeekdayMetadata),
177 Tuesday => Metadata::new(7, self, WeekdayMetadata),
178 Wednesday => Metadata::new(9, self, WeekdayMetadata),
179 Thursday => Metadata::new(8, self, WeekdayMetadata),
180 Friday => Metadata::new(6, self, WeekdayMetadata),
181 Saturday => Metadata::new(8, self, WeekdayMetadata),
182 Sunday => Metadata::new(6, self, WeekdayMetadata),
183 }
184 }
185
186 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
187 f.pad(match self {
188 Monday => "Monday",
189 Tuesday => "Tuesday",
190 Wednesday => "Wednesday",
191 Thursday => "Thursday",
192 Friday => "Friday",
193 Saturday => "Saturday",
194 Sunday => "Sunday",
195 })
196 }
197}
198
199impl fmt::Display for Weekday {
200 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
201 SmartDisplay::fmt(self, f)
202 }
203}
204
205impl FromStr for Weekday {
206 type Err = error::InvalidVariant;
207
208 fn from_str(s: &str) -> Result<Self, Self::Err> {
209 match s {
210 "Monday" => Ok(Monday),
211 "Tuesday" => Ok(Tuesday),
212 "Wednesday" => Ok(Wednesday),
213 "Thursday" => Ok(Thursday),
214 "Friday" => Ok(Friday),
215 "Saturday" => Ok(Saturday),
216 "Sunday" => Ok(Sunday),
217 _ => Err(error::InvalidVariant),
218 }
219 }
220}