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
173impl SmartDisplay for Weekday {
174 type Metadata = ();
175
176 #[inline]
177 fn metadata(&self, _: FormatterOptions) -> Metadata<'_, Self> {
178 match self {
179 Monday => Metadata::new(6, self, ()),
180 Tuesday => Metadata::new(7, self, ()),
181 Wednesday => Metadata::new(9, self, ()),
182 Thursday => Metadata::new(8, self, ()),
183 Friday => Metadata::new(6, self, ()),
184 Saturday => Metadata::new(8, self, ()),
185 Sunday => Metadata::new(6, self, ()),
186 }
187 }
188
189 #[inline]
190 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
191 f.pad(match self {
192 Monday => "Monday",
193 Tuesday => "Tuesday",
194 Wednesday => "Wednesday",
195 Thursday => "Thursday",
196 Friday => "Friday",
197 Saturday => "Saturday",
198 Sunday => "Sunday",
199 })
200 }
201}
202
203impl fmt::Display for Weekday {
204 #[inline]
205 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
206 SmartDisplay::fmt(self, f)
207 }
208}
209
210impl FromStr for Weekday {
211 type Err = error::InvalidVariant;
212
213 #[inline]
214 fn from_str(s: &str) -> Result<Self, Self::Err> {
215 match s {
216 "Monday" => Ok(Monday),
217 "Tuesday" => Ok(Tuesday),
218 "Wednesday" => Ok(Wednesday),
219 "Thursday" => Ok(Thursday),
220 "Friday" => Ok(Friday),
221 "Saturday" => Ok(Saturday),
222 "Sunday" => Ok(Sunday),
223 _ => Err(error::InvalidVariant),
224 }
225 }
226}