1use core::fmt;
4use core::str::FromStr;
5
6use powerfmt::smart_display::{FormatterOptions, Metadata, SmartDisplay};
7
8use self::Weekday::*;
9use crate::error;
10
11#[repr(u8)]
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
17pub enum Weekday {
18 #[expect(missing_docs)]
19 Monday,
20 #[expect(missing_docs)]
21 Tuesday,
22 #[expect(missing_docs)]
23 Wednesday,
24 #[expect(missing_docs)]
25 Thursday,
26 #[expect(missing_docs)]
27 Friday,
28 #[expect(missing_docs)]
29 Saturday,
30 #[expect(missing_docs)]
31 Sunday,
32}
33
34impl Weekday {
35 #[inline]
42 pub const fn previous(self) -> Self {
43 match self {
44 Monday => Sunday,
45 Tuesday => Monday,
46 Wednesday => Tuesday,
47 Thursday => Wednesday,
48 Friday => Thursday,
49 Saturday => Friday,
50 Sunday => Saturday,
51 }
52 }
53
54 #[inline]
61 pub const fn next(self) -> Self {
62 match self {
63 Monday => Tuesday,
64 Tuesday => Wednesday,
65 Wednesday => Thursday,
66 Thursday => Friday,
67 Friday => Saturday,
68 Saturday => Sunday,
69 Sunday => Monday,
70 }
71 }
72
73 #[inline]
81 pub const fn nth_next(self, n: u8) -> Self {
82 match (self.number_days_from_monday() + n % 7) % 7 {
83 0 => Monday,
84 1 => Tuesday,
85 2 => Wednesday,
86 3 => Thursday,
87 4 => Friday,
88 5 => Saturday,
89 val => {
90 debug_assert!(val == 6);
91 Sunday
92 }
93 }
94 }
95
96 #[inline]
104 pub const fn nth_prev(self, n: u8) -> Self {
105 match self.number_days_from_monday().cast_signed() - (n % 7).cast_signed() {
106 1 | -6 => Tuesday,
107 2 | -5 => Wednesday,
108 3 | -4 => Thursday,
109 4 | -3 => Friday,
110 5 | -2 => Saturday,
111 6 | -1 => Sunday,
112 val => {
113 debug_assert!(val == 0);
114 Monday
115 }
116 }
117 }
118
119 #[doc(alias = "iso_weekday_number")]
126 #[inline]
127 pub const fn number_from_monday(self) -> u8 {
128 self.number_days_from_monday() + 1
129 }
130
131 #[inline]
138 pub const fn number_from_sunday(self) -> u8 {
139 self.number_days_from_sunday() + 1
140 }
141
142 #[inline]
149 pub const fn number_days_from_monday(self) -> u8 {
150 self as u8
151 }
152
153 #[inline]
160 pub const fn number_days_from_sunday(self) -> u8 {
161 match self {
162 Monday => 1,
163 Tuesday => 2,
164 Wednesday => 3,
165 Thursday => 4,
166 Friday => 5,
167 Saturday => 6,
168 Sunday => 0,
169 }
170 }
171}
172
173mod private {
174 #[non_exhaustive]
176 #[derive(Debug, Clone, Copy)]
177 pub struct WeekdayMetadata;
178}
179use private::WeekdayMetadata;
180
181impl SmartDisplay for Weekday {
182 type Metadata = WeekdayMetadata;
183
184 #[inline]
185 fn metadata(&self, _: FormatterOptions) -> Metadata<'_, Self> {
186 match self {
187 Monday => Metadata::new(6, self, WeekdayMetadata),
188 Tuesday => Metadata::new(7, self, WeekdayMetadata),
189 Wednesday => Metadata::new(9, self, WeekdayMetadata),
190 Thursday => Metadata::new(8, self, WeekdayMetadata),
191 Friday => Metadata::new(6, self, WeekdayMetadata),
192 Saturday => Metadata::new(8, self, WeekdayMetadata),
193 Sunday => Metadata::new(6, self, WeekdayMetadata),
194 }
195 }
196
197 #[inline]
198 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
199 f.pad(match self {
200 Monday => "Monday",
201 Tuesday => "Tuesday",
202 Wednesday => "Wednesday",
203 Thursday => "Thursday",
204 Friday => "Friday",
205 Saturday => "Saturday",
206 Sunday => "Sunday",
207 })
208 }
209}
210
211impl fmt::Display for Weekday {
212 #[inline]
213 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
214 SmartDisplay::fmt(self, f)
215 }
216}
217
218impl FromStr for Weekday {
219 type Err = error::InvalidVariant;
220
221 #[inline]
222 fn from_str(s: &str) -> Result<Self, Self::Err> {
223 match s {
224 "Monday" => Ok(Monday),
225 "Tuesday" => Ok(Tuesday),
226 "Wednesday" => Ok(Wednesday),
227 "Thursday" => Ok(Thursday),
228 "Friday" => Ok(Friday),
229 "Saturday" => Ok(Saturday),
230 "Sunday" => Ok(Sunday),
231 _ => Err(error::InvalidVariant),
232 }
233 }
234}