1use crate::error::*;
2use crate::ordinal::{Ordinal, OrdinalSet};
3use crate::time_unit::TimeUnitField;
4use once_cell::sync::Lazy;
5use phf::phf_map;
6use std::borrow::Cow;
7
8static MONTH_MAP: phf::Map<&'static str, Ordinal> = phf_map! {
9 "jan" => 1,
10 "january" => 1,
11 "feb" => 2,
12 "february" => 2,
13 "mar" => 3,
14 "march" => 3,
15 "apr" => 4,
16 "april" => 4,
17 "may" => 5,
18 "jun" => 6,
19 "june" => 6,
20 "jul" => 7,
21 "july" => 7,
22 "aug" => 8,
23 "august" => 8,
24 "sep" => 9,
25 "september" => 9,
26 "oct" => 10,
27 "october" => 10,
28 "nov" => 11,
29 "november" => 11,
30 "dec" => 12,
31 "december" => 12,
32};
33
34static ALL: Lazy<OrdinalSet> = Lazy::new(Months::supported_ordinals);
35
36#[derive(Clone, Debug, Eq)]
37pub struct Months {
38 ordinals: Option<OrdinalSet>,
39}
40
41impl TimeUnitField for Months {
42 fn from_optional_ordinal_set(ordinal_set: Option<OrdinalSet>) -> Self {
43 Months {
44 ordinals: ordinal_set,
45 }
46 }
47 fn name() -> Cow<'static, str> {
48 Cow::from("Months")
49 }
50 fn inclusive_min() -> Ordinal {
51 1
52 }
53 fn inclusive_max() -> Ordinal {
54 12
55 }
56 fn ordinal_from_name(name: &str) -> Result<Ordinal, Error> {
57 MONTH_MAP
58 .get(name.to_lowercase().as_ref())
59 .copied()
60 .ok_or_else(|| {
61 ErrorKind::Expression(format!("'{}' is not a valid month name.", name)).into()
62 })
63 }
64 fn ordinals(&self) -> &OrdinalSet {
65 match &self.ordinals {
66 Some(ordinal_set) => ordinal_set,
67 None => &ALL,
68 }
69 }
70}
71
72impl PartialEq for Months {
73 fn eq(&self, other: &Months) -> bool {
74 self.ordinals() == other.ordinals()
75 }
76}