icu_capi/
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#[diplomat::bridge]
6pub mod ffi {
7    use alloc::boxed::Box;
8    use alloc::sync::Arc;
9
10    use core::fmt::Write;
11    use icu_calendar::{AnyCalendar, AnyCalendarKind};
12
13    use crate::errors::ffi::ICU4XError;
14    use crate::locale::ffi::ICU4XLocale;
15    use crate::provider::ffi::ICU4XDataProvider;
16
17    /// The various calendar types currently supported by [`ICU4XCalendar`]
18    #[diplomat::enum_convert(AnyCalendarKind, needs_wildcard)]
19    #[diplomat::rust_link(icu::calendar::AnyCalendarKind, Enum)]
20    pub enum ICU4XAnyCalendarKind {
21        /// The kind of an Iso calendar
22        Iso = 0,
23        /// The kind of a Gregorian calendar
24        Gregorian = 1,
25        /// The kind of a Buddhist calendar
26        Buddhist = 2,
27        /// The kind of a Japanese calendar with modern eras
28        Japanese = 3,
29        /// The kind of a Japanese calendar with modern and historic eras
30        JapaneseExtended = 4,
31        /// The kind of an Ethiopian calendar, with Amete Mihret era
32        Ethiopian = 5,
33        /// The kind of an Ethiopian calendar, with Amete Alem era
34        EthiopianAmeteAlem = 6,
35        /// The kind of a Indian calendar
36        Indian = 7,
37        /// The kind of a Coptic calendar
38        Coptic = 8,
39        /// The kind of a Dangi calendar
40        Dangi = 9,
41        /// The kind of a Chinese calendar
42        Chinese = 10,
43        /// The kind of a Hebrew calendar
44        Hebrew = 11,
45        /// The kind of a Islamic civil calendar
46        IslamicCivil = 12,
47        /// The kind of a Islamic observational calendar
48        IslamicObservational = 13,
49        /// The kind of a Islamic tabular calendar
50        IslamicTabular = 14,
51        /// The kind of a Islamic Umm al-Qura calendar
52        IslamicUmmAlQura = 15,
53        /// The kind of a Persian calendar
54        Persian = 16,
55        /// The kind of a Roc calendar
56        Roc = 17,
57    }
58
59    impl ICU4XAnyCalendarKind {
60        /// Read the calendar type off of the -u-ca- extension on a locale.
61        ///
62        /// Returns nothing if there is no calendar on the locale or if the locale's calendar
63        /// is not known or supported.
64        #[diplomat::rust_link(icu::calendar::AnyCalendarKind::get_for_locale, FnInEnum)]
65        pub fn get_for_locale(locale: &ICU4XLocale) -> Option<ICU4XAnyCalendarKind> {
66            AnyCalendarKind::get_for_locale(&locale.0).map(Into::into)
67        }
68
69        /// Obtain the calendar type given a BCP-47 -u-ca- extension string.
70        ///
71        /// Returns nothing if the calendar is not known or supported.
72        #[diplomat::rust_link(icu::calendar::AnyCalendarKind::get_for_bcp47_value, FnInEnum)]
73        #[diplomat::rust_link(
74            icu::calendar::AnyCalendarKind::get_for_bcp47_string,
75            FnInEnum,
76            hidden
77        )]
78        #[diplomat::rust_link(
79            icu::calendar::AnyCalendarKind::get_for_bcp47_bytes,
80            FnInEnum,
81            hidden
82        )]
83        pub fn get_for_bcp47(s: &DiplomatStr) -> Option<ICU4XAnyCalendarKind> {
84            AnyCalendarKind::get_for_bcp47_bytes(s).map(Into::into)
85        }
86
87        /// Obtain the string suitable for use in the -u-ca- extension in a BCP47 locale.
88        #[diplomat::rust_link(icu::calendar::AnyCalendarKind::as_bcp47_string, FnInEnum)]
89        #[diplomat::rust_link(icu::calendar::AnyCalendarKind::as_bcp47_value, FnInEnum, hidden)]
90        #[diplomat::attr(supports = accessors, getter)]
91        pub fn bcp47(
92            self,
93            write: &mut diplomat_runtime::DiplomatWriteable,
94        ) -> Result<(), ICU4XError> {
95            let kind = AnyCalendarKind::from(self);
96            Ok(write.write_str(kind.as_bcp47_string())?)
97        }
98    }
99
100    #[diplomat::opaque]
101    #[diplomat::transparent_convert]
102    #[diplomat::rust_link(icu::calendar::AnyCalendar, Enum)]
103    pub struct ICU4XCalendar(pub Arc<AnyCalendar>);
104
105    impl ICU4XCalendar {
106        /// Creates a new [`ICU4XCalendar`] from the specified date and time.
107        #[diplomat::rust_link(icu::calendar::AnyCalendar::new_for_locale, FnInEnum)]
108        #[diplomat::attr(all(supports = constructors, supports = fallible_constructors, supports = named_constructors), named_constructor = "for_locale")]
109        pub fn create_for_locale(
110            provider: &ICU4XDataProvider,
111            locale: &ICU4XLocale,
112        ) -> Result<Box<ICU4XCalendar>, ICU4XError> {
113            let locale = locale.to_datalocale();
114
115            Ok(Box::new(ICU4XCalendar(Arc::new(call_constructor!(
116                AnyCalendar::new_for_locale [r => Ok(r)],
117                AnyCalendar::try_new_for_locale_with_any_provider,
118                AnyCalendar::try_new_for_locale_with_buffer_provider,
119                provider,
120                &locale
121            )?))))
122        }
123
124        /// Creates a new [`ICU4XCalendar`] from the specified date and time.
125        #[diplomat::rust_link(icu::calendar::AnyCalendar::new, FnInEnum)]
126        #[diplomat::attr(all(supports = constructors, supports = fallible_constructors, supports = named_constructors), named_constructor = "for_kind")]
127        pub fn create_for_kind(
128            provider: &ICU4XDataProvider,
129            kind: ICU4XAnyCalendarKind,
130        ) -> Result<Box<ICU4XCalendar>, ICU4XError> {
131            Ok(Box::new(ICU4XCalendar(Arc::new(call_constructor!(
132                AnyCalendar::new [r => Ok(r)],
133                AnyCalendar::try_new_with_any_provider,
134                AnyCalendar::try_new_with_buffer_provider,
135                provider,
136                kind.into()
137            )?))))
138        }
139
140        /// Returns the kind of this calendar
141        #[diplomat::rust_link(icu::calendar::AnyCalendar::kind, FnInEnum)]
142        #[diplomat::attr(supports = accessors, getter)]
143        pub fn kind(&self) -> ICU4XAnyCalendarKind {
144            self.0.kind().into()
145        }
146    }
147}