1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
/// Enumeration of all months in a year.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub enum Month {
    /// The month of January.
    January,
    /// The month of February.
    February,
    /// The month of March.
    March,
    /// The month of April.
    April,
    /// The month of May.
    May,
    /// The month of June.
    June,
    /// The month of July.
    July,
    /// The month of August.
    August,
    /// The month of September.
    September,
    /// The month of October.
    October,
    /// The month of November.
    November,
    /// The month of December.
    December,
}

impl Month {
    #[doc(hidden)]
    pub fn prev(self) -> Self {
        let index: i32 = self.into();
        MONTH_LIST[(((index - 1) + 12) % 12) as usize]
    }

    #[doc(hidden)]
    pub fn number_of_days(self, year: i32) -> i32 {
        match self {
            Month::February => {
                if (year % 4 == 0 && year % 100 != 0) || year % 400 == 0 {
                    29
                } else {
                    28
                }
            }
            Month::January
            | Month::March
            | Month::May
            | Month::July
            | Month::August
            | Month::October
            | Month::December => 31,
            Month::April | Month::June | Month::September | Month::November => 30,
        }
    }

    #[doc(hidden)]
    pub fn prev_number_of_days(self, year: i32) -> i32 {
        match self {
            Month::January => self.prev().number_of_days(year - 1),
            _ => self.prev().number_of_days(year),
        }
    }
}

// Statics --------------------------------------------------------------------
static MONTH_LIST: [Month; 12] = [
    Month::January,
    Month::February,
    Month::March,
    Month::April,
    Month::May,
    Month::June,
    Month::July,
    Month::August,
    Month::September,
    Month::October,
    Month::November,
    Month::December,
];

// Conversions ----------------------------------------------------------------
impl From<u32> for Month {
    fn from(index: u32) -> Self {
        MONTH_LIST[index as usize]
    }
}

impl<'a> Into<i32> for Month {
    fn into(self) -> i32 {
        match self {
            Month::January => 0,
            Month::February => 1,
            Month::March => 2,
            Month::April => 3,
            Month::May => 4,
            Month::June => 5,
            Month::July => 6,
            Month::August => 7,
            Month::September => 8,
            Month::October => 9,
            Month::November => 10,
            Month::December => 11,
        }
    }
}