mirror of
https://git.proxmox.com/git/rustc
synced 2026-03-29 03:51:39 +00:00
264 lines
7.0 KiB
Rust
264 lines
7.0 KiB
Rust
//! The `Month` enum and its associated `impl`s.
|
|
|
|
use core::fmt;
|
|
use core::num::NonZeroU8;
|
|
use core::str::FromStr;
|
|
|
|
use powerfmt::smart_display::{FormatterOptions, Metadata, SmartDisplay};
|
|
|
|
use self::Month::*;
|
|
use crate::error;
|
|
|
|
/// Months of the year.
|
|
#[repr(u8)]
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
pub enum Month {
|
|
#[allow(missing_docs)]
|
|
January = 1,
|
|
#[allow(missing_docs)]
|
|
February = 2,
|
|
#[allow(missing_docs)]
|
|
March = 3,
|
|
#[allow(missing_docs)]
|
|
April = 4,
|
|
#[allow(missing_docs)]
|
|
May = 5,
|
|
#[allow(missing_docs)]
|
|
June = 6,
|
|
#[allow(missing_docs)]
|
|
July = 7,
|
|
#[allow(missing_docs)]
|
|
August = 8,
|
|
#[allow(missing_docs)]
|
|
September = 9,
|
|
#[allow(missing_docs)]
|
|
October = 10,
|
|
#[allow(missing_docs)]
|
|
November = 11,
|
|
#[allow(missing_docs)]
|
|
December = 12,
|
|
}
|
|
|
|
impl Month {
|
|
/// Create a `Month` from its numerical value.
|
|
pub(crate) const fn from_number(n: NonZeroU8) -> Result<Self, error::ComponentRange> {
|
|
match n.get() {
|
|
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),
|
|
n => Err(error::ComponentRange {
|
|
name: "month",
|
|
minimum: 1,
|
|
maximum: 12,
|
|
value: n as _,
|
|
conditional_range: false,
|
|
}),
|
|
}
|
|
}
|
|
|
|
/// Get the previous month.
|
|
///
|
|
/// ```rust
|
|
/// # use time::Month;
|
|
/// assert_eq!(Month::January.previous(), Month::December);
|
|
/// ```
|
|
pub const fn previous(self) -> Self {
|
|
match self {
|
|
January => December,
|
|
February => January,
|
|
March => February,
|
|
April => March,
|
|
May => April,
|
|
June => May,
|
|
July => June,
|
|
August => July,
|
|
September => August,
|
|
October => September,
|
|
November => October,
|
|
December => November,
|
|
}
|
|
}
|
|
|
|
/// Get the next month.
|
|
///
|
|
/// ```rust
|
|
/// # use time::Month;
|
|
/// assert_eq!(Month::January.next(), Month::February);
|
|
/// ```
|
|
pub const fn next(self) -> Self {
|
|
match self {
|
|
January => February,
|
|
February => March,
|
|
March => April,
|
|
April => May,
|
|
May => June,
|
|
June => July,
|
|
July => August,
|
|
August => September,
|
|
September => October,
|
|
October => November,
|
|
November => December,
|
|
December => January,
|
|
}
|
|
}
|
|
|
|
/// Get n-th next month.
|
|
///
|
|
/// ```rust
|
|
/// # use time::Month;
|
|
/// assert_eq!(Month::January.nth_next(4), Month::May);
|
|
/// assert_eq!(Month::July.nth_next(9), Month::April);
|
|
/// ```
|
|
pub const fn nth_next(self, n: u8) -> Self {
|
|
match (self as u8 - 1 + n % 12) % 12 {
|
|
0 => January,
|
|
1 => February,
|
|
2 => March,
|
|
3 => April,
|
|
4 => May,
|
|
5 => June,
|
|
6 => July,
|
|
7 => August,
|
|
8 => September,
|
|
9 => October,
|
|
10 => November,
|
|
val => {
|
|
debug_assert!(val == 11);
|
|
December
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Get n-th previous month.
|
|
///
|
|
/// ```rust
|
|
/// # use time::Month;
|
|
/// assert_eq!(Month::January.nth_prev(4), Month::September);
|
|
/// assert_eq!(Month::July.nth_prev(9), Month::October);
|
|
/// ```
|
|
pub const fn nth_prev(self, n: u8) -> Self {
|
|
match self as i8 - 1 - (n % 12) as i8 {
|
|
1 | -11 => February,
|
|
2 | -10 => March,
|
|
3 | -9 => April,
|
|
4 | -8 => May,
|
|
5 | -7 => June,
|
|
6 | -6 => July,
|
|
7 | -5 => August,
|
|
8 | -4 => September,
|
|
9 | -3 => October,
|
|
10 | -2 => November,
|
|
11 | -1 => December,
|
|
val => {
|
|
debug_assert!(val == 0);
|
|
January
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
mod private {
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone, Copy)]
|
|
pub struct MonthMetadata;
|
|
}
|
|
use private::MonthMetadata;
|
|
|
|
impl SmartDisplay for Month {
|
|
type Metadata = MonthMetadata;
|
|
|
|
fn metadata(&self, _: FormatterOptions) -> Metadata<Self> {
|
|
match self {
|
|
January => Metadata::new(7, self, MonthMetadata),
|
|
February => Metadata::new(8, self, MonthMetadata),
|
|
March => Metadata::new(5, self, MonthMetadata),
|
|
April => Metadata::new(5, self, MonthMetadata),
|
|
May => Metadata::new(3, self, MonthMetadata),
|
|
June => Metadata::new(4, self, MonthMetadata),
|
|
July => Metadata::new(4, self, MonthMetadata),
|
|
August => Metadata::new(6, self, MonthMetadata),
|
|
September => Metadata::new(9, self, MonthMetadata),
|
|
October => Metadata::new(7, self, MonthMetadata),
|
|
November => Metadata::new(8, self, MonthMetadata),
|
|
December => Metadata::new(8, self, MonthMetadata),
|
|
}
|
|
}
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
f.pad(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 fmt::Display for Month {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
SmartDisplay::fmt(self, f)
|
|
}
|
|
}
|
|
|
|
impl FromStr for Month {
|
|
type Err = error::InvalidVariant;
|
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
match s {
|
|
"January" => Ok(January),
|
|
"February" => Ok(February),
|
|
"March" => Ok(March),
|
|
"April" => Ok(April),
|
|
"May" => Ok(May),
|
|
"June" => Ok(June),
|
|
"July" => Ok(July),
|
|
"August" => Ok(August),
|
|
"September" => Ok(September),
|
|
"October" => Ok(October),
|
|
"November" => Ok(November),
|
|
"December" => Ok(December),
|
|
_ => Err(error::InvalidVariant),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<Month> for u8 {
|
|
fn from(month: Month) -> Self {
|
|
month as _
|
|
}
|
|
}
|
|
|
|
impl TryFrom<u8> for Month {
|
|
type Error = error::ComponentRange;
|
|
|
|
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
|
match NonZeroU8::new(value) {
|
|
Some(value) => Self::from_number(value),
|
|
None => Err(error::ComponentRange {
|
|
name: "month",
|
|
minimum: 1,
|
|
maximum: 12,
|
|
value: 0,
|
|
conditional_range: false,
|
|
}),
|
|
}
|
|
}
|
|
}
|