Coverage Report

Created: 2025-08-12 06:35

/rust/registry/src/index.crates.io-6f17d22bba15001f/time-0.3.37/src/month.rs
Line
Count
Source (jump to first uncovered line)
1
//! The `Month` enum and its associated `impl`s.
2
3
use core::fmt;
4
use core::num::NonZeroU8;
5
use core::str::FromStr;
6
7
use powerfmt::smart_display::{FormatterOptions, Metadata, SmartDisplay};
8
9
use self::Month::*;
10
use crate::{error, util};
11
12
/// Months of the year.
13
#[repr(u8)]
14
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
15
pub enum Month {
16
    #[allow(missing_docs)]
17
    January = 1,
18
    #[allow(missing_docs)]
19
    February = 2,
20
    #[allow(missing_docs)]
21
    March = 3,
22
    #[allow(missing_docs)]
23
    April = 4,
24
    #[allow(missing_docs)]
25
    May = 5,
26
    #[allow(missing_docs)]
27
    June = 6,
28
    #[allow(missing_docs)]
29
    July = 7,
30
    #[allow(missing_docs)]
31
    August = 8,
32
    #[allow(missing_docs)]
33
    September = 9,
34
    #[allow(missing_docs)]
35
    October = 10,
36
    #[allow(missing_docs)]
37
    November = 11,
38
    #[allow(missing_docs)]
39
    December = 12,
40
}
41
42
impl Month {
43
    /// Create a `Month` from its numerical value.
44
0
    pub(crate) const fn from_number(n: NonZeroU8) -> Result<Self, error::ComponentRange> {
45
0
        match n.get() {
46
0
            1 => Ok(January),
47
0
            2 => Ok(February),
48
0
            3 => Ok(March),
49
0
            4 => Ok(April),
50
0
            5 => Ok(May),
51
0
            6 => Ok(June),
52
0
            7 => Ok(July),
53
0
            8 => Ok(August),
54
0
            9 => Ok(September),
55
0
            10 => Ok(October),
56
0
            11 => Ok(November),
57
0
            12 => Ok(December),
58
0
            n => Err(error::ComponentRange {
59
0
                name: "month",
60
0
                minimum: 1,
61
0
                maximum: 12,
62
0
                value: n as _,
63
0
                conditional_range: false,
64
0
            }),
65
        }
66
0
    }
67
68
    /// Get the number of days in the month of a given year.
69
    ///
70
    /// ```rust
71
    /// # use time::Month;
72
    /// assert_eq!(Month::February.length(2020), 29);
73
    /// ```
74
0
    pub const fn length(self, year: i32) -> u8 {
75
0
        match self {
76
0
            January | March | May | July | August | October | December => 31,
77
0
            April | June | September | November => 30,
78
0
            February if util::is_leap_year(year) => 29,
79
0
            February => 28,
80
        }
81
0
    }
82
83
    /// Get the previous month.
84
    ///
85
    /// ```rust
86
    /// # use time::Month;
87
    /// assert_eq!(Month::January.previous(), Month::December);
88
    /// ```
89
0
    pub const fn previous(self) -> Self {
90
0
        match self {
91
0
            January => December,
92
0
            February => January,
93
0
            March => February,
94
0
            April => March,
95
0
            May => April,
96
0
            June => May,
97
0
            July => June,
98
0
            August => July,
99
0
            September => August,
100
0
            October => September,
101
0
            November => October,
102
0
            December => November,
103
        }
104
0
    }
105
106
    /// Get the next month.
107
    ///
108
    /// ```rust
109
    /// # use time::Month;
110
    /// assert_eq!(Month::January.next(), Month::February);
111
    /// ```
112
0
    pub const fn next(self) -> Self {
113
0
        match self {
114
0
            January => February,
115
0
            February => March,
116
0
            March => April,
117
0
            April => May,
118
0
            May => June,
119
0
            June => July,
120
0
            July => August,
121
0
            August => September,
122
0
            September => October,
123
0
            October => November,
124
0
            November => December,
125
0
            December => January,
126
        }
127
0
    }
128
129
    /// Get n-th next month.
130
    ///
131
    /// ```rust
132
    /// # use time::Month;
133
    /// assert_eq!(Month::January.nth_next(4), Month::May);
134
    /// assert_eq!(Month::July.nth_next(9), Month::April);
135
    /// ```
136
0
    pub const fn nth_next(self, n: u8) -> Self {
137
0
        match (self as u8 - 1 + n % 12) % 12 {
138
0
            0 => January,
139
0
            1 => February,
140
0
            2 => March,
141
0
            3 => April,
142
0
            4 => May,
143
0
            5 => June,
144
0
            6 => July,
145
0
            7 => August,
146
0
            8 => September,
147
0
            9 => October,
148
0
            10 => November,
149
0
            val => {
150
0
                debug_assert!(val == 11);
151
0
                December
152
            }
153
        }
154
0
    }
155
156
    /// Get n-th previous month.
157
    ///
158
    /// ```rust
159
    /// # use time::Month;
160
    /// assert_eq!(Month::January.nth_prev(4), Month::September);
161
    /// assert_eq!(Month::July.nth_prev(9), Month::October);
162
    /// ```
163
0
    pub const fn nth_prev(self, n: u8) -> Self {
164
0
        match self as i8 - 1 - (n % 12) as i8 {
165
0
            1 | -11 => February,
166
0
            2 | -10 => March,
167
0
            3 | -9 => April,
168
0
            4 | -8 => May,
169
0
            5 | -7 => June,
170
0
            6 | -6 => July,
171
0
            7 | -5 => August,
172
0
            8 | -4 => September,
173
0
            9 | -3 => October,
174
0
            10 | -2 => November,
175
0
            11 | -1 => December,
176
0
            val => {
177
0
                debug_assert!(val == 0);
178
0
                January
179
            }
180
        }
181
0
    }
182
}
183
184
mod private {
185
    #[non_exhaustive]
186
    #[derive(Debug, Clone, Copy)]
187
    pub struct MonthMetadata;
188
}
189
use private::MonthMetadata;
190
191
impl SmartDisplay for Month {
192
    type Metadata = MonthMetadata;
193
194
0
    fn metadata(&self, _: FormatterOptions) -> Metadata<Self> {
195
0
        match self {
196
0
            January => Metadata::new(7, self, MonthMetadata),
197
0
            February => Metadata::new(8, self, MonthMetadata),
198
0
            March => Metadata::new(5, self, MonthMetadata),
199
0
            April => Metadata::new(5, self, MonthMetadata),
200
0
            May => Metadata::new(3, self, MonthMetadata),
201
0
            June => Metadata::new(4, self, MonthMetadata),
202
0
            July => Metadata::new(4, self, MonthMetadata),
203
0
            August => Metadata::new(6, self, MonthMetadata),
204
0
            September => Metadata::new(9, self, MonthMetadata),
205
0
            October => Metadata::new(7, self, MonthMetadata),
206
0
            November => Metadata::new(8, self, MonthMetadata),
207
0
            December => Metadata::new(8, self, MonthMetadata),
208
        }
209
0
    }
210
211
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
212
0
        f.pad(match self {
213
0
            January => "January",
214
0
            February => "February",
215
0
            March => "March",
216
0
            April => "April",
217
0
            May => "May",
218
0
            June => "June",
219
0
            July => "July",
220
0
            August => "August",
221
0
            September => "September",
222
0
            October => "October",
223
0
            November => "November",
224
0
            December => "December",
225
        })
226
0
    }
227
}
228
229
impl fmt::Display for Month {
230
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
231
0
        SmartDisplay::fmt(self, f)
232
0
    }
233
}
234
235
impl FromStr for Month {
236
    type Err = error::InvalidVariant;
237
238
0
    fn from_str(s: &str) -> Result<Self, Self::Err> {
239
0
        match s {
240
0
            "January" => Ok(January),
241
0
            "February" => Ok(February),
242
0
            "March" => Ok(March),
243
0
            "April" => Ok(April),
244
0
            "May" => Ok(May),
245
0
            "June" => Ok(June),
246
0
            "July" => Ok(July),
247
0
            "August" => Ok(August),
248
0
            "September" => Ok(September),
249
0
            "October" => Ok(October),
250
0
            "November" => Ok(November),
251
0
            "December" => Ok(December),
252
0
            _ => Err(error::InvalidVariant),
253
        }
254
0
    }
255
}
256
257
impl From<Month> for u8 {
258
0
    fn from(month: Month) -> Self {
259
0
        month as _
260
0
    }
261
}
262
263
impl TryFrom<u8> for Month {
264
    type Error = error::ComponentRange;
265
266
0
    fn try_from(value: u8) -> Result<Self, Self::Error> {
267
0
        match NonZeroU8::new(value) {
268
0
            Some(value) => Self::from_number(value),
269
0
            None => Err(error::ComponentRange {
270
0
                name: "month",
271
0
                minimum: 1,
272
0
                maximum: 12,
273
0
                value: 0,
274
0
                conditional_range: false,
275
0
            }),
276
        }
277
0
    }
278
}