| //! Days of the week. |
| |
| use core::fmt; |
| use core::str::FromStr; |
| |
| use powerfmt::smart_display::{FormatterOptions, Metadata, SmartDisplay}; |
| |
| use self::Weekday::*; |
| use crate::error; |
| |
| /// Days of the week. |
| /// |
| /// As order is dependent on context (Sunday could be either two days after or five days before |
| /// Friday), this type does not implement `PartialOrd` or `Ord`. |
| #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
| pub enum Weekday { |
| #[allow(missing_docs)] |
| Monday, |
| #[allow(missing_docs)] |
| Tuesday, |
| #[allow(missing_docs)] |
| Wednesday, |
| #[allow(missing_docs)] |
| Thursday, |
| #[allow(missing_docs)] |
| Friday, |
| #[allow(missing_docs)] |
| Saturday, |
| #[allow(missing_docs)] |
| Sunday, |
| } |
| |
| impl Weekday { |
| /// Get the previous weekday. |
| /// |
| /// ```rust |
| /// # use time::Weekday; |
| /// assert_eq!(Weekday::Tuesday.previous(), Weekday::Monday); |
| /// ``` |
| pub const fn previous(self) -> Self { |
| match self { |
| Monday => Sunday, |
| Tuesday => Monday, |
| Wednesday => Tuesday, |
| Thursday => Wednesday, |
| Friday => Thursday, |
| Saturday => Friday, |
| Sunday => Saturday, |
| } |
| } |
| |
| /// Get the next weekday. |
| /// |
| /// ```rust |
| /// # use time::Weekday; |
| /// assert_eq!(Weekday::Monday.next(), Weekday::Tuesday); |
| /// ``` |
| pub const fn next(self) -> Self { |
| match self { |
| Monday => Tuesday, |
| Tuesday => Wednesday, |
| Wednesday => Thursday, |
| Thursday => Friday, |
| Friday => Saturday, |
| Saturday => Sunday, |
| Sunday => Monday, |
| } |
| } |
| |
| /// Get n-th next day. |
| /// |
| /// ```rust |
| /// # use time::Weekday; |
| /// assert_eq!(Weekday::Monday.nth_next(1), Weekday::Tuesday); |
| /// assert_eq!(Weekday::Sunday.nth_next(10), Weekday::Wednesday); |
| /// ``` |
| pub const fn nth_next(self, n: u8) -> Self { |
| match (self.number_days_from_monday() + n % 7) % 7 { |
| 0 => Monday, |
| 1 => Tuesday, |
| 2 => Wednesday, |
| 3 => Thursday, |
| 4 => Friday, |
| 5 => Saturday, |
| val => { |
| debug_assert!(val == 6); |
| Sunday |
| } |
| } |
| } |
| |
| /// Get n-th previous day. |
| /// |
| /// ```rust |
| /// # use time::Weekday; |
| /// assert_eq!(Weekday::Monday.nth_prev(1), Weekday::Sunday); |
| /// assert_eq!(Weekday::Sunday.nth_prev(10), Weekday::Thursday); |
| /// ``` |
| pub const fn nth_prev(self, n: u8) -> Self { |
| match self.number_days_from_monday() as i8 - (n % 7) as i8 { |
| 1 | -6 => Tuesday, |
| 2 | -5 => Wednesday, |
| 3 | -4 => Thursday, |
| 4 | -3 => Friday, |
| 5 | -2 => Saturday, |
| 6 | -1 => Sunday, |
| val => { |
| debug_assert!(val == 0); |
| Monday |
| } |
| } |
| } |
| |
| /// Get the one-indexed number of days from Monday. |
| /// |
| /// ```rust |
| /// # use time::Weekday; |
| /// assert_eq!(Weekday::Monday.number_from_monday(), 1); |
| /// ``` |
| #[doc(alias = "iso_weekday_number")] |
| pub const fn number_from_monday(self) -> u8 { |
| self.number_days_from_monday() + 1 |
| } |
| |
| /// Get the one-indexed number of days from Sunday. |
| /// |
| /// ```rust |
| /// # use time::Weekday; |
| /// assert_eq!(Weekday::Monday.number_from_sunday(), 2); |
| /// ``` |
| pub const fn number_from_sunday(self) -> u8 { |
| self.number_days_from_sunday() + 1 |
| } |
| |
| /// Get the zero-indexed number of days from Monday. |
| /// |
| /// ```rust |
| /// # use time::Weekday; |
| /// assert_eq!(Weekday::Monday.number_days_from_monday(), 0); |
| /// ``` |
| pub const fn number_days_from_monday(self) -> u8 { |
| self as _ |
| } |
| |
| /// Get the zero-indexed number of days from Sunday. |
| /// |
| /// ```rust |
| /// # use time::Weekday; |
| /// assert_eq!(Weekday::Monday.number_days_from_sunday(), 1); |
| /// ``` |
| pub const fn number_days_from_sunday(self) -> u8 { |
| match self { |
| Monday => 1, |
| Tuesday => 2, |
| Wednesday => 3, |
| Thursday => 4, |
| Friday => 5, |
| Saturday => 6, |
| Sunday => 0, |
| } |
| } |
| } |
| |
| mod private { |
| #[non_exhaustive] |
| #[derive(Debug, Clone, Copy)] |
| pub struct WeekdayMetadata; |
| } |
| use private::WeekdayMetadata; |
| |
| impl SmartDisplay for Weekday { |
| type Metadata = WeekdayMetadata; |
| |
| fn metadata(&self, _: FormatterOptions) -> Metadata<'_, Self> { |
| match self { |
| Monday => Metadata::new(6, self, WeekdayMetadata), |
| Tuesday => Metadata::new(7, self, WeekdayMetadata), |
| Wednesday => Metadata::new(9, self, WeekdayMetadata), |
| Thursday => Metadata::new(8, self, WeekdayMetadata), |
| Friday => Metadata::new(6, self, WeekdayMetadata), |
| Saturday => Metadata::new(8, self, WeekdayMetadata), |
| Sunday => Metadata::new(6, self, WeekdayMetadata), |
| } |
| } |
| |
| fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| f.pad(match self { |
| Monday => "Monday", |
| Tuesday => "Tuesday", |
| Wednesday => "Wednesday", |
| Thursday => "Thursday", |
| Friday => "Friday", |
| Saturday => "Saturday", |
| Sunday => "Sunday", |
| }) |
| } |
| } |
| |
| impl fmt::Display for Weekday { |
| fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| SmartDisplay::fmt(self, f) |
| } |
| } |
| |
| impl FromStr for Weekday { |
| type Err = error::InvalidVariant; |
| |
| fn from_str(s: &str) -> Result<Self, Self::Err> { |
| match s { |
| "Monday" => Ok(Monday), |
| "Tuesday" => Ok(Tuesday), |
| "Wednesday" => Ok(Wednesday), |
| "Thursday" => Ok(Thursday), |
| "Friday" => Ok(Friday), |
| "Saturday" => Ok(Saturday), |
| "Sunday" => Ok(Sunday), |
| _ => Err(error::InvalidVariant), |
| } |
| } |
| } |