Skip to main content

whichtime_sys/dictionaries/
en.rs

1//! English locale dictionaries
2
3use super::{CasualDateType, CasualTimeType, RelativeModifier, TimeUnit, Weekday};
4use phf::phf_map;
5
6/// Weekday dictionary - maps lowercase weekday names to Weekday enum
7pub static WEEKDAY_MAP: phf::Map<&'static str, Weekday> = phf_map! {
8    "sunday" => Weekday::Sunday,
9    "sun" => Weekday::Sunday,
10    "sun." => Weekday::Sunday,
11    "monday" => Weekday::Monday,
12    "mon" => Weekday::Monday,
13    "mon." => Weekday::Monday,
14    "tuesday" => Weekday::Tuesday,
15    "tue" => Weekday::Tuesday,
16    "tue." => Weekday::Tuesday,
17    "tues" => Weekday::Tuesday,
18    "wednesday" => Weekday::Wednesday,
19    "wed" => Weekday::Wednesday,
20    "wed." => Weekday::Wednesday,
21    "thursday" => Weekday::Thursday,
22    "thu" => Weekday::Thursday,
23    "thu." => Weekday::Thursday,
24    "thur" => Weekday::Thursday,
25    "thur." => Weekday::Thursday,
26    "thurs" => Weekday::Thursday,
27    "thurs." => Weekday::Thursday,
28    "friday" => Weekday::Friday,
29    "fri" => Weekday::Friday,
30    "fri." => Weekday::Friday,
31    "saturday" => Weekday::Saturday,
32    "sat" => Weekday::Saturday,
33    "sat." => Weekday::Saturday,
34};
35
36/// Month dictionary - maps lowercase month names to 1-based month numbers
37pub static MONTH_MAP: phf::Map<&'static str, u32> = phf_map! {
38    "january" => 1,
39    "jan" => 1,
40    "jan." => 1,
41    "february" => 2,
42    "feb" => 2,
43    "feb." => 2,
44    "march" => 3,
45    "mar" => 3,
46    "mar." => 3,
47    "april" => 4,
48    "apr" => 4,
49    "apr." => 4,
50    "may" => 5,
51    "june" => 6,
52    "jun" => 6,
53    "jun." => 6,
54    "july" => 7,
55    "jul" => 7,
56    "jul." => 7,
57    "august" => 8,
58    "aug" => 8,
59    "aug." => 8,
60    "september" => 9,
61    "sep" => 9,
62    "sep." => 9,
63    "sept" => 9,
64    "sept." => 9,
65    "october" => 10,
66    "oct" => 10,
67    "oct." => 10,
68    "november" => 11,
69    "nov" => 11,
70    "nov." => 11,
71    "december" => 12,
72    "dec" => 12,
73    "dec." => 12,
74};
75
76/// Integer words dictionary
77pub static INTEGER_WORD_MAP: phf::Map<&'static str, f64> = phf_map! {
78    "one" => 1.0,
79    "two" => 2.0,
80    "three" => 3.0,
81    "four" => 4.0,
82    "five" => 5.0,
83    "six" => 6.0,
84    "seven" => 7.0,
85    "eight" => 8.0,
86    "nine" => 9.0,
87    "ten" => 10.0,
88    "eleven" => 11.0,
89    "twelve" => 12.0,
90};
91
92/// Ordinal words dictionary
93pub static ORDINAL_WORD_MAP: phf::Map<&'static str, u32> = phf_map! {
94    "first" => 1,
95    "second" => 2,
96    "third" => 3,
97    "fourth" => 4,
98    "fifth" => 5,
99    "sixth" => 6,
100    "seventh" => 7,
101    "eighth" => 8,
102    "ninth" => 9,
103    "tenth" => 10,
104    "eleventh" => 11,
105    "twelfth" => 12,
106    "thirteenth" => 13,
107    "fourteenth" => 14,
108    "fifteenth" => 15,
109    "sixteenth" => 16,
110    "seventeenth" => 17,
111    "eighteenth" => 18,
112    "nineteenth" => 19,
113    "twentieth" => 20,
114    "twenty first" => 21,
115    "twenty-first" => 21,
116    "twenty second" => 22,
117    "twenty-second" => 22,
118    "twenty third" => 23,
119    "twenty-third" => 23,
120    "twenty fourth" => 24,
121    "twenty-fourth" => 24,
122    "twenty fifth" => 25,
123    "twenty-fifth" => 25,
124    "twenty sixth" => 26,
125    "twenty-sixth" => 26,
126    "twenty seventh" => 27,
127    "twenty-seventh" => 27,
128    "twenty eighth" => 28,
129    "twenty-eighth" => 28,
130    "twenty ninth" => 29,
131    "twenty-ninth" => 29,
132    "thirtieth" => 30,
133    "thirty first" => 31,
134    "thirty-first" => 31,
135};
136
137/// Time unit dictionary (with abbreviations)
138pub static TIME_UNIT_MAP: phf::Map<&'static str, TimeUnit> = phf_map! {
139    "second" => TimeUnit::Second,
140    "seconds" => TimeUnit::Second,
141    "sec" => TimeUnit::Second,
142    "secs" => TimeUnit::Second,
143    "s" => TimeUnit::Second,
144    "minute" => TimeUnit::Minute,
145    "minutes" => TimeUnit::Minute,
146    "min" => TimeUnit::Minute,
147    "mins" => TimeUnit::Minute,
148    "m" => TimeUnit::Minute,
149    "hour" => TimeUnit::Hour,
150    "hours" => TimeUnit::Hour,
151    "hr" => TimeUnit::Hour,
152    "hrs" => TimeUnit::Hour,
153    "h" => TimeUnit::Hour,
154    "day" => TimeUnit::Day,
155    "days" => TimeUnit::Day,
156    "d" => TimeUnit::Day,
157    "week" => TimeUnit::Week,
158    "weeks" => TimeUnit::Week,
159    "w" => TimeUnit::Week,
160    "month" => TimeUnit::Month,
161    "months" => TimeUnit::Month,
162    "mo" => TimeUnit::Month,
163    "mos" => TimeUnit::Month,
164    "quarter" => TimeUnit::Quarter,
165    "quarters" => TimeUnit::Quarter,
166    "qtr" => TimeUnit::Quarter,
167    "year" => TimeUnit::Year,
168    "years" => TimeUnit::Year,
169    "yr" => TimeUnit::Year,
170    "yrs" => TimeUnit::Year,
171    "y" => TimeUnit::Year,
172};
173
174/// Casual date keywords
175pub static CASUAL_DATE_MAP: phf::Map<&'static str, CasualDateType> = phf_map! {
176    "now" => CasualDateType::Now,
177    "today" => CasualDateType::Today,
178    "tonight" => CasualDateType::Tonight,
179    "tomorrow" => CasualDateType::Tomorrow,
180    "tmr" => CasualDateType::Tomorrow,
181    "tmrw" => CasualDateType::Tomorrow,
182    "yesterday" => CasualDateType::Yesterday,
183    "overmorrow" => CasualDateType::Overmorrow,
184};
185
186/// Casual time keywords
187pub static CASUAL_TIME_MAP: phf::Map<&'static str, CasualTimeType> = phf_map! {
188    "noon" => CasualTimeType::Noon,
189    "midday" => CasualTimeType::Noon,
190    "midnight" => CasualTimeType::Midnight,
191    "morning" => CasualTimeType::Morning,
192    "afternoon" => CasualTimeType::Afternoon,
193    "evening" => CasualTimeType::Evening,
194    "night" => CasualTimeType::Night,
195};
196
197/// Relative modifiers
198pub static RELATIVE_MODIFIER_MAP: phf::Map<&'static str, RelativeModifier> = phf_map! {
199    "this" => RelativeModifier::This,
200    "next" => RelativeModifier::Next,
201    "last" => RelativeModifier::Last,
202    "past" => RelativeModifier::Last,
203    "previous" => RelativeModifier::Last,
204    "coming" => RelativeModifier::Next,
205    "following" => RelativeModifier::Next,
206};
207
208// ============================================================================
209// Lookup functions
210// ============================================================================
211
212#[inline]
213pub fn get_weekday(s: &str) -> Option<Weekday> {
214    WEEKDAY_MAP.get(s).copied()
215}
216
217#[inline]
218pub fn get_month(s: &str) -> Option<u32> {
219    MONTH_MAP.get(s).copied()
220}
221
222#[inline]
223pub fn get_integer_word(s: &str) -> Option<f64> {
224    INTEGER_WORD_MAP.get(s).copied()
225}
226
227#[inline]
228pub fn get_ordinal_word(s: &str) -> Option<u32> {
229    ORDINAL_WORD_MAP.get(s).copied()
230}
231
232#[inline]
233pub fn get_time_unit(s: &str) -> Option<TimeUnit> {
234    TIME_UNIT_MAP.get(s).copied()
235}
236
237#[inline]
238pub fn get_casual_date(s: &str) -> Option<CasualDateType> {
239    CASUAL_DATE_MAP.get(s).copied()
240}
241
242#[inline]
243pub fn get_casual_time(s: &str) -> Option<CasualTimeType> {
244    CASUAL_TIME_MAP.get(s).copied()
245}
246
247#[inline]
248pub fn get_relative_modifier(s: &str) -> Option<RelativeModifier> {
249    RELATIVE_MODIFIER_MAP.get(s).copied()
250}
251
252/// Parse a number pattern (handles words, numbers, and special cases)
253pub fn parse_number_pattern(text: &str) -> f64 {
254    let lower = text.to_lowercase();
255
256    if let Some(val) = get_integer_word(&lower) {
257        return val;
258    }
259
260    match lower.as_str() {
261        "a" | "an" | "the" => return 1.0,
262        s if s.contains("few") => return 3.0,
263        s if s.contains("half") => return 0.5,
264        s if s.contains("couple") => return 2.0,
265        s if s.contains("several") => return 7.0,
266        _ => {}
267    }
268
269    text.parse::<f64>().unwrap_or(0.0)
270}
271
272/// Parse an ordinal number pattern
273pub fn parse_ordinal_pattern(text: &str) -> Option<u32> {
274    let lower = text.to_lowercase();
275
276    if let Some(val) = get_ordinal_word(&lower) {
277        return Some(val);
278    }
279
280    let cleaned = lower
281        .trim_end_matches("st")
282        .trim_end_matches("nd")
283        .trim_end_matches("rd")
284        .trim_end_matches("th");
285
286    cleaned.parse::<u32>().ok()
287}