Skip to main content

icu_locale_core/preferences/extensions/unicode/keywords/
calendar.rs

1// This file is part of ICU4X. For terms of use, please see the file
2// called LICENSE at the top level of the ICU4X source tree
3// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
4
5#![allow(non_snake_case)]
6
7use crate::extensions::unicode::{value, Value};
8use crate::preferences::extensions::unicode::enum_keyword;
9use crate::preferences::extensions::unicode::errors::PreferencesParseError;
10use crate::subtags::{subtag, Subtag};
11
12enum_keyword!(
13    /// Hijri Calendar sub-type
14    ///
15    /// The list is based on [`CLDR Calendars`](https://github.com/unicode-org/cldr/blob/main/common/bcp47/calendar.xml)
16    HijriCalendarAlgorithm {
17        /// Hijri calendar, Umm al-Qura
18        Umalqura,
19        /// Hijri calendar, tabular (intercalary years \[2,5,7,10,13,16,18,21,24,26,29] - astronomical epoch)
20        Tbla,
21        /// Hijri calendar, tabular (intercalary years \[2,5,7,10,13,16,18,21,24,26,29] - civil epoch)
22        Civil,
23        /// Hijri calendar, Saudi Arabia sighting
24        Rgsa
25});
26
27/// Handles aliases present in `v`. If found, returns a [`CalendarAlgorithm`], else returns None
28fn handle_aliases(v: &Value) -> Option<CalendarAlgorithm> {
29    if *v == value!("islamicc") {
30        return Some(CalendarAlgorithm::Hijri(Some(
31            HijriCalendarAlgorithm::Civil,
32        )));
33    } else if v.as_subtags_slice() == [subtag!("ethiopic"), subtag!("amete"), subtag!("alem")] {
34        return Some(CalendarAlgorithm::Ethioaa);
35    }
36    None
37}
38
39enum_keyword!(
40    /// A Unicode Calendar Identifier defines a type of calendar.
41    ///
42    /// This selects calendar-specific data within a locale used for formatting and parsing,
43    /// such as date/time symbols and patterns; it also selects supplemental calendarData used
44    /// for calendrical calculations. The value can affect the computation of the first day of the week.
45    ///
46    /// The valid values are listed in [LDML](https://unicode.org/reports/tr35/#UnicodeCalendarIdentifier).
47    CalendarAlgorithm {
48        /// Thai Buddhist calendar (same as Gregorian except for the year)
49        ("buddhist" => Buddhist),
50        /// Traditional Chinese calendar
51        ("chinese" => Chinese),
52        /// Coptic calendar
53        ("coptic" => Coptic),
54        /// Traditional Korean calendar
55        ("dangi" => Dangi),
56        /// Ethiopic calendar, Amete Alem (epoch approx. 5493 B.C.E)
57        ("ethioaa" => Ethioaa),
58        /// Ethiopic calendar, Amete Mihret (epoch approx, 8 C.E.)
59        ("ethiopic" => Ethiopic),
60        /// Gregorian calendar
61        ("gregory" => Gregory),
62        /// Traditional Hebrew calendar
63        ("hebrew" => Hebrew),
64        /// Indian calendar
65        ("indian" => Indian),
66        /// Hijri calendar
67        ("islamic" => Hijri(HijriCalendarAlgorithm) {
68             ("umalqura" => Umalqura),
69             ("tbla" => Tbla),
70             ("civil" => Civil),
71             ("rgsa" => Rgsa)
72        }),
73        /// ISO calendar (Gregorian calendar using the ISO 8601 calendar week rules)
74        ("iso8601" => Iso8601),
75        /// Japanese Imperial calendar
76        ("japanese" => Japanese),
77        /// Persian calendar
78        ("persian" => Persian),
79        /// Republic of China calendar
80        ("roc" => Roc)
81}, "ca", s, if let Some(s) = handle_aliases(s) { return Ok(s) });
82
83#[test]
84fn test_calendar_aliases() {
85    fn test(s: &str, expectation: CalendarAlgorithm) {
86        let v = Value::try_from_str(s).unwrap();
87        let parsed = CalendarAlgorithm::try_from(&v).unwrap();
88        assert_eq!(parsed, expectation, "{s} must parse to {expectation:?}");
89    }
90
91    test("ethiopic-amete-alem", CalendarAlgorithm::Ethioaa);
92    test("ethiopic", CalendarAlgorithm::Ethiopic);
93    test("ethioaa", CalendarAlgorithm::Ethioaa);
94    test(
95        "islamicc",
96        CalendarAlgorithm::Hijri(Some(HijriCalendarAlgorithm::Civil)),
97    );
98    test(
99        "islamic-civil",
100        CalendarAlgorithm::Hijri(Some(HijriCalendarAlgorithm::Civil)),
101    );
102    test(
103        "islamic-rgsa",
104        CalendarAlgorithm::Hijri(Some(HijriCalendarAlgorithm::Rgsa)),
105    );
106    test("islamic", CalendarAlgorithm::Hijri(None));
107}