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