dia_time/
weekday.rs

1/*
2==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--
3
4Dia-Time
5
6Copyright (C) 2018-2022, 2024  Anonymous
7
8There are several releases over multiple years,
9they are listed as ranges, such as: "2018-2022".
10
11This program is free software: you can redistribute it and/or modify
12it under the terms of the GNU Lesser General Public License as published by
13the Free Software Foundation, either version 3 of the License, or
14(at your option) any later version.
15
16This program is distributed in the hope that it will be useful,
17but WITHOUT ANY WARRANTY; without even the implied warranty of
18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19GNU Lesser General Public License for more details.
20
21You should have received a copy of the GNU Lesser General Public License
22along with this program.  If not, see <https://www.gnu.org/licenses/>.
23
24::--::--::--::--::--::--::--::--::--::--::--::--::--::--::--::--
25*/
26
27//! # Weekday
28
29use {
30    core::{
31        fmt::{self, Debug, Display, Formatter},
32        ops::Deref,
33        str::FromStr,
34    },
35    crate::{Error, Result as CrateResult},
36};
37
38#[cfg(test)]
39mod tests;
40
41/// # Weekday
42///
43/// ## Notes
44///
45/// -   First day of the week is Monday (see [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601)).
46/// -   The days' names are English only. That applies to implementations of [`FromStr`][trait:core/str/FromStr],
47///     [`Deref<Target=str>`][trait:core/ops/Deref]...
48/// -   Implementation of `Deref<Target=str>` is same as [`Display`][trait:core/fmt/Display]'s, but it's faster because it provides references
49///     to static strings.
50///
51/// [trait:core/fmt/Display]: https://doc.rust-lang.org/core/fmt/trait.Display.html
52/// [trait:core/ops/Deref]: https://doc.rust-lang.org/core/ops/trait.Deref.html
53/// [trait:core/str/FromStr]: https://doc.rust-lang.org/core/str/trait.FromStr.html
54#[derive(Debug, Eq, PartialEq, Hash, Ord, PartialOrd, Clone, Copy)]
55pub enum Weekday {
56
57    /// # Monday,
58    Monday,
59
60    /// # Tuesday,
61    Tuesday,
62
63    /// # Wednesday,
64    Wednesday,
65
66    /// # Thursday,
67    Thursday,
68
69    /// # Friday
70    Friday,
71
72    /// # Saturday
73    Saturday,
74
75    /// # Sunday
76    Sunday,
77
78}
79
80impl Weekday {
81
82    /// # Gets next day
83    pub const fn next(&self) -> Option<Self> {
84        match self {
85            Weekday::Monday => Some(Weekday::Tuesday),
86            Weekday::Tuesday => Some(Weekday::Wednesday),
87            Weekday::Wednesday => Some(Weekday::Thursday),
88            Weekday::Thursday => Some(Weekday::Friday),
89            Weekday::Friday => Some(Weekday::Saturday),
90            Weekday::Saturday => Some(Weekday::Sunday),
91            Weekday::Sunday => None,
92        }
93    }
94
95    /// # Gets next day
96    ///
97    /// Next of Sunday will be Monday.
98    pub const fn wrapping_next(&self) -> Self {
99        match self {
100            Weekday::Monday => Weekday::Tuesday,
101            Weekday::Tuesday => Weekday::Wednesday,
102            Weekday::Wednesday => Weekday::Thursday,
103            Weekday::Thursday => Weekday::Friday,
104            Weekday::Friday => Weekday::Saturday,
105            Weekday::Saturday => Weekday::Sunday,
106            Weekday::Sunday => Weekday::Monday,
107        }
108    }
109
110    /// # Gets last day
111    pub const fn last(&self) -> Option<Self> {
112        match self {
113            Weekday::Monday => None,
114            Weekday::Tuesday => Some(Weekday::Monday),
115            Weekday::Wednesday => Some(Weekday::Tuesday),
116            Weekday::Thursday => Some(Weekday::Wednesday),
117            Weekday::Friday => Some(Weekday::Thursday),
118            Weekday::Saturday => Some(Weekday::Friday),
119            Weekday::Sunday => Some(Weekday::Saturday),
120        }
121    }
122
123    /// # Gets last day
124    ///
125    /// Last of Monday will be Sunday.
126    pub const fn wrapping_last(&self) -> Self {
127        match self {
128            Weekday::Monday => Weekday::Sunday,
129            Weekday::Tuesday => Weekday::Monday,
130            Weekday::Wednesday => Weekday::Tuesday,
131            Weekday::Thursday => Weekday::Wednesday,
132            Weekday::Friday => Weekday::Thursday,
133            Weekday::Saturday => Weekday::Friday,
134            Weekday::Sunday => Weekday::Saturday,
135        }
136    }
137
138    /// # Tries to convert a Unix value into self
139    pub (crate) fn try_from_unix(weekday: i64) -> CrateResult<Self> {
140        match weekday {
141            0 => Ok(Weekday::Sunday),
142            1 => Ok(Weekday::Monday),
143            2 => Ok(Weekday::Tuesday),
144            3 => Ok(Weekday::Wednesday),
145            4 => Ok(Weekday::Thursday),
146            5 => Ok(Weekday::Friday),
147            6 => Ok(Weekday::Saturday),
148            _ => Err(err!("Invalid Unix weekday: {weekday}", weekday=weekday)),
149        }
150    }
151
152}
153
154impl Deref for Weekday {
155
156    type Target = str;
157
158    fn deref(&self) -> &Self::Target {
159        match self {
160            Weekday::Monday => "Monday",
161            Weekday::Tuesday => "Tuesday",
162            Weekday::Wednesday => "Wednesday",
163            Weekday::Thursday => "Thursday",
164            Weekday::Friday => "Friday",
165            Weekday::Saturday => "Saturday",
166            Weekday::Sunday => "Sunday",
167        }
168    }
169
170}
171
172impl Display for Weekday {
173
174    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
175        f.write_str(self)
176    }
177
178}
179
180impl FromStr for Weekday {
181
182    type Err = Error;
183
184    fn from_str(s: &str) -> Result<Self, Self::Err> {
185        if s.eq_ignore_ascii_case(&*Weekday::Monday) {
186            Ok(Weekday::Monday)
187        } else if s.eq_ignore_ascii_case(&*Weekday::Tuesday) {
188            Ok(Weekday::Tuesday)
189        } else if s.eq_ignore_ascii_case(&*Weekday::Wednesday) {
190            Ok(Weekday::Wednesday)
191        } else if s.eq_ignore_ascii_case(&*Weekday::Thursday) {
192            Ok(Weekday::Thursday)
193        } else if s.eq_ignore_ascii_case(&*Weekday::Friday) {
194            Ok(Weekday::Friday)
195        } else if s.eq_ignore_ascii_case(&*Weekday::Saturday) {
196            Ok(Weekday::Saturday)
197        } else if s.eq_ignore_ascii_case(&*Weekday::Sunday) {
198            Ok(Weekday::Sunday)
199        } else {
200            Err(err!("Unknown weekday: {:?}", s))
201        }
202    }
203
204}