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}