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}