Skip to main content

deep_time/alloc_parse/
types.rs

1use crate::Dt;
2use alloc::string::String;
3use alloc::vec::Vec;
4
5#[derive(Clone, Copy, Debug, PartialEq, Default)]
6#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7#[cfg_attr(feature = "tsify", derive(tsify::Tsify))]
8pub enum Order {
9    /// **Default & recommended** — Smart modern heuristic (best of all worlds):
10    /// - Tries **Year-first** formats first (modern/tech bias: JSON, logs, APIs, databases)
11    /// - Then Day-first (international/European)
12    /// - Then Month-first (US fallback)
13    ///
14    /// This gives the best real-world success rate while remaining predictable.
15    #[default]
16    Smart,
17    /// Force **Year-first** only (YYYY/MM/DD or YY/MM/DD)
18    Year,
19    /// Force **Day-first** only (DD/MM/YYYY)
20    Day,
21    /// Force **Month-first** only (MM/DD/YYYY)
22    Month,
23}
24
25#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
26#[cfg_attr(feature = "tsify", derive(tsify::Tsify))]
27#[derive(Clone, Copy, Debug, Default, PartialEq)]
28/// Only relevant for purely numeric dates.
29pub enum Mode {
30    /// **Default mode** — Smart heuristic:
31    /// - 5/7-digit pure-numeric inside `LEGACY_ORDINAL_YEAR_RANGE` → treated as business ordinal (YYYYDDD / YYDDD)
32    /// - Outside that range or invalid ordinal → treated as MJD or JD
33    #[default]
34    Auto,
35    /// When combined with a provided Vec of formats in parse no other formats are tried.
36    Explicit,
37    /// It's some sort of unix timestamp
38    UnixTimestamp,
39    /// Business/legacy-only mode:
40    /// Only accepts ordinal dates (YYYYDDD / YYDDD). No astronomy (JD/MJD) support.
41    /// Strict and predictable for ERP/mainframe data.
42    Legacy,
43    /// Scientific / astronomy-first mode:
44    /// Prioritizes MJD (5-digit) and JD (7-digit). Ordinals are only fallback.
45    /// Use this when parsing data from astronomy tools or large numeric epochs.
46    Scientific,
47}
48
49#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
50#[cfg_attr(feature = "tsify", derive(tsify::Tsify))]
51#[derive(Clone, Debug, PartialEq)]
52pub struct ParseCfg {
53    /// Explicit list of formats to try **in the exact order given**.
54    ///
55    /// If this is provided and the vec is non-empty and the mode is Explicit
56    /// then only these formats are tried and `mode` and `order` are ignored.
57    ///
58    /// If the mode is not Explicit then after trying the formats in parse the
59    /// rest of the parser will continue as normal, using `mode` and `order`.
60    ///
61    /// Example:
62    /// ```js
63    /// parse: ["%Y-%m-%d", "%d/%m/%Y", "%m/%d/%Y", "%d.%m.%Y"]
64    /// ```
65    #[cfg_attr(feature = "serde", serde(default))]
66    pub parse: Option<Vec<String>>,
67
68    /// Controls which preset format sets are used (astronomy/scientific formats,
69    /// legacy business rules, etc.).
70    #[cfg_attr(feature = "serde", serde(default))]
71    pub mode: Mode,
72
73    /// Controls ambiguous numeric dates.
74    #[cfg_attr(feature = "serde", serde(default))]
75    pub order: Order,
76
77    /// Sets language to use, not persistent.
78    #[cfg_attr(feature = "serde", serde(default))]
79    pub lang: Lang,
80
81    /// Whether to lowercase the input:
82    /// ONLY set to `false` if the &str is already lowercase.
83    #[cfg_attr(feature = "serde", serde(default = "default_true"))]
84    pub to_lower: bool,
85
86    /// Whether to parse relative dates as well as normal dates.
87    #[cfg_attr(feature = "serde", serde(default = "default_true"))]
88    pub relative: bool,
89
90    /// **Reference ("current") time** used for relative expressions:
91    /// - "tomorrow", "next Friday", "in 3 days", "next week"
92    /// - dates missing a year/month ("March 15", "15th of next month")
93    ///
94    /// - If `Some(tp)`, this `Dt` is used as "now" (overrides everything).
95    /// - If `None` + `std` feature enabled: automatically uses real system time.
96    /// - If `None` + no `std`: parsing relative dates will fail with a clear error.
97    #[cfg_attr(feature = "serde", serde(default))]
98    pub ref_time: Option<Dt>,
99}
100
101#[cfg(feature = "serde")]
102fn default_true() -> bool {
103    true
104}
105
106impl Default for ParseCfg {
107    fn default() -> Self {
108        Self {
109            parse: None,
110            mode: Mode::default(),
111            order: Order::default(),
112            lang: Lang::default(),
113            to_lower: true,
114            relative: true,
115            ref_time: None,
116        }
117    }
118}
119
120#[derive(Debug, Clone, Copy, PartialEq, Eq)]
121pub(crate) enum OrderFirst {
122    /// Year-Month-Day ordering (ISO 8601 style, `YYYY-MM-DD`, `20240315`, etc.)
123    Year,
124    /// Month-Day-Year ordering (US / some English locales, `MM/DD/YYYY`)
125    Month,
126    /// Day-Month-Year ordering (most of the world, `DD/MM/YYYY`, `DD.MM.YYYY`)
127    Day,
128}
129
130#[derive(Clone)]
131pub(crate) struct AmBuilder {
132    pub pieces: Vec<&'static str>,
133    pub seen_year: bool,
134    pub seen_month: bool,
135    pub seen_day: bool,
136}
137
138#[inline]
139pub(crate) fn append_to_all(builders: &mut Vec<AmBuilder>, s: &'static str) {
140    for b in builders {
141        b.pieces.push(s);
142    }
143}
144
145/// Language codes following ISO 639-1 standard (two-letter codes)
146/// Default is En (English)
147#[allow(dead_code)]
148#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
149#[cfg_attr(feature = "tsify", derive(tsify::Tsify))]
150#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
151pub enum Lang {
152    /// English (default)
153    #[default]
154    En,
155    /// Afar
156    Aa,
157    /// Abkhazian
158    Ab,
159    /// Avestan
160    Ae,
161    /// Afrikaans
162    Af,
163    /// Akan
164    Ak,
165    /// Amharic
166    Am,
167    /// Aragonese
168    An,
169    /// Arabic
170    Ar,
171    /// Assamese
172    As,
173    /// Avaric
174    Av,
175    /// Aymara
176    Ay,
177    /// Azerbaijani
178    Az,
179    /// Bashkir
180    Ba,
181    /// Belarusian
182    Be,
183    /// Bulgarian
184    Bg,
185    /// Bihari languages
186    Bh,
187    /// Bislama
188    Bi,
189    /// Bambara
190    Bm,
191    /// Bengali
192    Bn,
193    /// Tibetan
194    Bo,
195    /// Breton
196    Br,
197    /// Bosnian
198    Bs,
199    /// Catalan
200    Ca,
201    /// Chechen
202    Ce,
203    /// Chamorro
204    Ch,
205    /// Corsican
206    Co,
207    /// Cree
208    Cr,
209    /// Czech
210    Cs,
211    /// Church Slavic
212    Cu,
213    /// Chuvash
214    Cv,
215    /// Welsh
216    Cy,
217    /// Danish
218    Da,
219    /// German
220    De,
221    /// Divehi
222    Dv,
223    /// Dzongkha
224    Dz,
225    /// Ewe
226    Ee,
227    /// Greek
228    El,
229    /// Esperanto
230    Eo,
231    /// Spanish
232    Es,
233    /// Estonian
234    Et,
235    /// Basque
236    Eu,
237    /// Persian
238    Fa,
239    /// Fulah
240    Ff,
241    /// Finnish
242    Fi,
243    /// Fijian
244    Fj,
245    /// Faroese
246    Fo,
247    /// French
248    Fr,
249    /// Western Frisian
250    Fy,
251    /// Irish
252    Ga,
253    /// Scottish Gaelic
254    Gd,
255    /// Galician
256    Gl,
257    /// Guarani
258    Gn,
259    /// Gujarati
260    Gu,
261    /// Manx
262    Gv,
263    /// Hausa
264    Ha,
265    /// Hebrew
266    He,
267    /// Hindi
268    Hi,
269    /// Hiri Motu
270    Ho,
271    /// Croatian
272    Hr,
273    /// Haitian Creole
274    Ht,
275    /// Hungarian
276    Hu,
277    /// Armenian
278    Hy,
279    /// Herero
280    Hz,
281    /// Interlingua
282    Ia,
283    /// Indonesian
284    Id,
285    /// Interlingue
286    Ie,
287    /// Igbo
288    Ig,
289    /// Sichuan Yi
290    Ii,
291    /// Inupiaq
292    Ik,
293    /// Ido
294    Io,
295    /// Icelandic
296    Is,
297    /// Italian
298    It,
299    /// Inuktitut
300    Iu,
301    /// Japanese
302    Ja,
303    /// Javanese
304    Jv,
305    /// Georgian
306    Ka,
307    /// Kongo
308    Kg,
309    /// Kikuyu
310    Ki,
311    /// Kuanyama
312    Kj,
313    /// Kazakh
314    Kk,
315    /// Greenlandic
316    Kl,
317    /// Khmer
318    Km,
319    /// Kannada
320    Kn,
321    /// Korean
322    Ko,
323    /// Kanuri
324    Kr,
325    /// Kashmiri
326    Ks,
327    /// Kurdish
328    Ku,
329    /// Komi
330    Kv,
331    /// Cornish
332    Kw,
333    /// Kyrgyz
334    Ky,
335    /// Latin
336    La,
337    /// Luxembourgish
338    Lb,
339    /// Ganda
340    Lg,
341    /// Limburgish
342    Li,
343    /// Lingala
344    Ln,
345    /// Lao
346    Lo,
347    /// Lithuanian
348    Lt,
349    /// Luba-Katanga
350    Lu,
351    /// Latvian
352    Lv,
353    /// Malagasy
354    Mg,
355    /// Marshallese
356    Mh,
357    /// Maori
358    Mi,
359    /// Macedonian
360    Mk,
361    /// Malayalam
362    Ml,
363    /// Mongolian
364    Mn,
365    /// Marathi
366    Mr,
367    /// Malay
368    Ms,
369    /// Maltese
370    Mt,
371    /// Burmese
372    My,
373    /// Nauru
374    Na,
375    /// Norwegian Bokmål
376    Nb,
377    /// North Ndebele
378    Nd,
379    /// Nepali
380    Ne,
381    /// Ndonga
382    Ng,
383    /// Dutch
384    Nl,
385    /// Norwegian Nynorsk
386    Nn,
387    /// Norwegian
388    No,
389    /// South Ndebele
390    Nr,
391    /// Navajo
392    Nv,
393    /// Chichewa
394    Ny,
395    /// Occitan
396    Oc,
397    /// Ojibwa
398    Oj,
399    /// Oromo
400    Om,
401    /// Oriya
402    Or,
403    /// Ossetian
404    Os,
405    /// Punjabi
406    Pa,
407    /// Pali
408    Pi,
409    /// Polish
410    Pl,
411    /// Pashto
412    Ps,
413    /// Portuguese
414    Pt,
415    /// Quechua
416    Qu,
417    /// Romansh
418    Rm,
419    /// Rundi
420    Rn,
421    /// Romanian
422    Ro,
423    /// Russian
424    Ru,
425    /// Kinyarwanda
426    Rw,
427    /// Sanskrit
428    Sa,
429    /// Sardinian
430    Sc,
431    /// Sindhi
432    Sd,
433    /// Northern Sami
434    Se,
435    /// Sango
436    Sg,
437    /// Sinhala
438    Si,
439    /// Slovak
440    Sk,
441    /// Slovenian
442    Sl,
443    /// Samoan
444    Sm,
445    /// Shona
446    Sn,
447    /// Somali
448    So,
449    /// Albanian
450    Sq,
451    /// Serbian
452    Sr,
453    /// Swati
454    Ss,
455    /// Southern Sotho
456    St,
457    /// Sundanese
458    Su,
459    /// Swedish
460    Sv,
461    /// Swahili
462    Sw,
463    /// Tamil
464    Ta,
465    /// Telugu
466    Te,
467    /// Tajik
468    Tg,
469    /// Thai
470    Th,
471    /// Tigrinya
472    Ti,
473    /// Turkmen
474    Tk,
475    /// Tagalog
476    Tl,
477    /// Tswana
478    Tn,
479    /// Tonga
480    To,
481    /// Turkish
482    Tr,
483    /// Tsonga
484    Ts,
485    /// Tatar
486    Tt,
487    /// Twi
488    Tw,
489    /// Tahitian
490    Ty,
491    /// Uyghur
492    Ug,
493    /// Ukrainian
494    Uk,
495    /// Urdu
496    Ur,
497    /// Uzbek
498    Uz,
499    /// Venda
500    Ve,
501    /// Vietnamese
502    Vi,
503    /// Volapük
504    Vo,
505    /// Walloon
506    Wa,
507    /// Wolof
508    Wo,
509    /// Xhosa
510    Xh,
511    /// Yiddish
512    Yi,
513    /// Yoruba
514    Yo,
515    /// Zhuang
516    Za,
517    /// Chinese
518    Zh,
519    /// Zulu
520    Zu,
521}
522
523impl alloc::fmt::Display for Lang {
524    fn fmt(&self, f: &mut alloc::fmt::Formatter<'_>) -> alloc::fmt::Result {
525        write!(f, "{:?}", self)
526    }
527}