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