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