devela/phys/time/calendar/
month.rsuse crate::{Display, FmtResult, Formatter, FromStr};
#[allow(clippy::enum_glob_use)]
use Month::*;
#[repr(u8)]
#[allow(missing_docs)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Ord, PartialOrd, Hash)]
pub enum Month {
January = 0,
February,
March,
April,
May,
June,
July,
August,
September,
October,
November,
December,
}
impl Month {
pub const COUNT: usize = 12;
#[allow(clippy::len_without_is_empty)]
pub const fn len(self, leap: bool) -> u8 {
match self {
January => 31,
February => 28 + leap as u8,
March => 31,
April => 30,
May => 31,
June => 30,
July => 31,
August => 31,
September => 30,
October => 31,
November => 30,
December => 31,
}
}
pub const fn previous(self) -> Month {
self.previous_nth(1)
}
pub const fn previous_nth(self, nth: usize) -> Month {
Self::from_index_unchecked(self.index().wrapping_sub(nth) % Self::COUNT)
}
pub const fn next(self) -> Month {
self.next_nth(1)
}
pub const fn next_nth(self, nth: usize) -> Month {
Self::from_index_unchecked(self.index().wrapping_add(nth) % Self::COUNT)
}
pub const fn number(self) -> u8 {
self.index() as u8 + 1
}
pub const fn index(self) -> usize {
self as _
}
pub const fn from_number(n: u8) -> Result<Month, &'static str> {
match n {
1 => Ok(January),
2 => Ok(February),
3 => Ok(March),
4 => Ok(April),
5 => Ok(May),
6 => Ok(June),
7 => Ok(July),
8 => Ok(August),
9 => Ok(September),
10 => Ok(October),
11 => Ok(November),
12 => Ok(December),
_ => Err("The month number must be between 1 and 12."),
}
}
pub const fn from_index(index: usize) -> Result<Month, &'static str> {
match index {
0 => Ok(January),
1 => Ok(February),
2 => Ok(March),
3 => Ok(April),
4 => Ok(May),
5 => Ok(June),
6 => Ok(July),
7 => Ok(August),
8 => Ok(September),
9 => Ok(October),
10 => Ok(November),
11 => Ok(December),
_ => Err("The month index must be between 0 and 11."),
}
}
pub const fn from_index_unchecked(index: usize) -> Self {
match index {
0 => January,
1 => February,
2 => March,
3 => April,
4 => May,
5 => June,
6 => July,
7 => August,
8 => September,
9 => October,
10 => November,
11 => December,
_ => panic!("The month index must be between 0 and 11."),
}
}
}
#[allow(missing_docs, non_upper_case_globals)]
impl Month {
pub const fn abbr3(self) -> &'static str {
match self {
January => "Jan",
February => "Feb",
March => "Mar",
April => "Apr",
May => "May",
June => "Jun",
July => "Jul",
August => "Aug",
September => "Sep",
October => "Oct",
November => "Nov",
December => "Dec",
}
}
pub const Jan: Month = Month::January;
pub const Feb: Month = Month::February;
pub const Mar: Month = Month::March;
pub const Apr: Month = Month::April;
pub const May: Month = Month::May;
pub const Jun: Month = Month::June;
pub const Jul: Month = Month::July;
pub const Aug: Month = Month::August;
pub const Sep: Month = Month::September;
pub const Oct: Month = Month::October;
pub const Nov: Month = Month::November;
pub const Dec: Month = Month::December;
pub const fn abbr2(self) -> &'static str {
match self {
January => "JA",
February => "FE",
March => "MR",
April => "AP",
May => "MY",
June => "JN",
July => "JL",
August => "AU",
September => "SE",
October => "OC",
November => "NV",
December => "DE",
}
}
pub const JA: Month = Month::January;
pub const FE: Month = Month::February;
pub const MR: Month = Month::March;
pub const AP: Month = Month::April;
pub const MY: Month = Month::May;
pub const JN: Month = Month::June;
pub const JL: Month = Month::July;
pub const AU: Month = Month::August;
pub const SE: Month = Month::September;
pub const OC: Month = Month::October;
pub const NV: Month = Month::November;
pub const DE: Month = Month::December;
pub const fn abbr1(self) -> &'static str {
match self {
January => "J",
February => "F",
March => "R",
April => "P",
May => "Y",
June => "N",
July => "L",
August => "U",
September => "S",
October => "O",
November => "N",
December => "D",
}
}
pub const J: Month = Month::January;
pub const F: Month = Month::February;
pub const R: Month = Month::March;
pub const P: Month = Month::April;
pub const Y: Month = Month::May;
pub const N: Month = Month::June;
pub const L: Month = Month::July;
pub const U: Month = Month::August;
pub const S: Month = Month::September;
pub const O: Month = Month::October;
pub const V: Month = Month::November;
pub const D: Month = Month::December;
pub const fn emoji(self) -> char {
match self {
January => '🌺',
February => '🐉',
March => '🍀',
April => '🐰',
May => '🌼',
June => '🐟',
July => '🌞',
August => '🍂',
September => '🎃',
October => '🦉',
November => '🍁',
December => '🎄',
}
}
pub const fn zodiac_start(self) -> char {
match self {
January => '♑',
February => '♒',
March => '♓',
April => '♈',
May => '♉',
June => '♊',
July => '♋',
August => '♌',
September => '♍',
October => '♎',
November => '♏',
December => '♐',
}
}
pub const fn zodiac_start_name(self) -> &'static str {
match self {
January => "Capricorn",
February => "Aquarius",
March => "Pisces",
April => "Aries",
May => "Taurus",
June => "Gemini",
July => "Cancer",
August => "Leo",
September => "Virgo",
October => "Libra",
November => "Scorpio",
December => "Sagittarius",
}
}
pub const fn zodiac_end(self) -> char {
self.next().zodiac_start()
}
pub const fn zodiac_end_name(self) -> &'static str {
self.next().zodiac_start_name()
}
}
impl Display for Month {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult<()> {
f.write_str(match self {
January => "January",
February => "February",
March => "March",
April => "April",
May => "May",
June => "June",
July => "July",
August => "August",
September => "September",
October => "October",
November => "November",
December => "December",
})
}
}
impl From<Month> for u8 {
fn from(month: Month) -> Self {
month as _
}
}
impl FromStr for Month {
type Err = &'static str;
#[rustfmt::skip]
fn from_str(s: &str) -> Result<Month, Self::Err> {
if s.eq_ignore_ascii_case("January") { Ok(January)
} else if s.eq_ignore_ascii_case("February") { Ok(February)
} else if s.eq_ignore_ascii_case("March") { Ok(March)
} else if s.eq_ignore_ascii_case("April") { Ok(April)
} else if s.eq_ignore_ascii_case("May") { Ok(May)
} else if s.eq_ignore_ascii_case("June") { Ok(June)
} else if s.eq_ignore_ascii_case("July") { Ok(July)
} else if s.eq_ignore_ascii_case("August") { Ok(August)
} else if s.eq_ignore_ascii_case("September") { Ok(September)
} else if s.eq_ignore_ascii_case("October") { Ok(October)
} else if s.eq_ignore_ascii_case("November") { Ok(November)
} else if s.eq_ignore_ascii_case("December") { Ok(December)
} else if s.eq_ignore_ascii_case("Jan") { Ok(January)
} else if s.eq_ignore_ascii_case("Feb") { Ok(February)
} else if s.eq_ignore_ascii_case("Mar") { Ok(March)
} else if s.eq_ignore_ascii_case("Apr") { Ok(April)
} else if s.eq_ignore_ascii_case("Jun") { Ok(June)
} else if s.eq_ignore_ascii_case("Jul") { Ok(July)
} else if s.eq_ignore_ascii_case("Aug") { Ok(August)
} else if s.eq_ignore_ascii_case("Sep") { Ok(September)
} else if s.eq_ignore_ascii_case("Oct") { Ok(October)
} else if s.eq_ignore_ascii_case("Nov") { Ok(November)
} else if s.eq_ignore_ascii_case("Dec") { Ok(December)
} else if s.eq_ignore_ascii_case("JA") { Ok(January)
} else if s.eq_ignore_ascii_case("FE") { Ok(February)
} else if s.eq_ignore_ascii_case("MR") { Ok(March)
} else if s.eq_ignore_ascii_case("AP") { Ok(April)
} else if s.eq_ignore_ascii_case("MY") { Ok(May)
} else if s.eq_ignore_ascii_case("JN") { Ok(June)
} else if s.eq_ignore_ascii_case("JL") { Ok(July)
} else if s.eq_ignore_ascii_case("AU") { Ok(August)
} else if s.eq_ignore_ascii_case("SE") { Ok(September)
} else if s.eq_ignore_ascii_case("OC") { Ok(October)
} else if s.eq_ignore_ascii_case("NV") { Ok(November)
} else if s.eq_ignore_ascii_case("DE") { Ok(December)
} else if s.eq_ignore_ascii_case("J") { Ok(January)
} else if s.eq_ignore_ascii_case("F") { Ok(February)
} else if s.eq_ignore_ascii_case("R") { Ok(March)
} else if s.eq_ignore_ascii_case("P") { Ok(April)
} else if s.eq_ignore_ascii_case("Y") { Ok(May)
} else if s.eq_ignore_ascii_case("N") { Ok(June)
} else if s.eq_ignore_ascii_case("L") { Ok(July)
} else if s.eq_ignore_ascii_case("U") { Ok(August)
} else if s.eq_ignore_ascii_case("S") { Ok(September)
} else if s.eq_ignore_ascii_case("O") { Ok(October)
} else if s.eq_ignore_ascii_case("V") { Ok(November)
} else if s.eq_ignore_ascii_case("D") { Ok(December)
} else {
Err("Invalid month name.")
}
}
}