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