summaryrefslogtreecommitdiffstats
path: root/intl/icu_capi/src/timezone_formatter.rs
diff options
context:
space:
mode:
Diffstat (limited to 'intl/icu_capi/src/timezone_formatter.rs')
-rw-r--r--intl/icu_capi/src/timezone_formatter.rs298
1 files changed, 298 insertions, 0 deletions
diff --git a/intl/icu_capi/src/timezone_formatter.rs b/intl/icu_capi/src/timezone_formatter.rs
new file mode 100644
index 0000000000..0cd4b04bc3
--- /dev/null
+++ b/intl/icu_capi/src/timezone_formatter.rs
@@ -0,0 +1,298 @@
+// This file is part of ICU4X. For terms of use, please see the file
+// called LICENSE at the top level of the ICU4X source tree
+// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
+
+use icu_datetime::time_zone::{FallbackFormat, TimeZoneFormatterOptions};
+
+macro_rules! call_method {
+ ($self:ident, $compiled:ident, $unstable:ident, $provider:expr) => {
+ match &$provider.0 {
+ $crate::provider::ICU4XDataProviderInner::Destroyed => Err(
+ icu_provider::DataError::custom("This provider has been destroyed"),
+ )?,
+ $crate::provider::ICU4XDataProviderInner::Empty => $self
+ .0
+ .$unstable(&icu_provider_adapters::empty::EmptyDataProvider::new()),
+ #[cfg(feature = "buffer_provider")]
+ $crate::provider::ICU4XDataProviderInner::Buffer(buffer_provider) => $self.0.$unstable(
+ &icu_provider::AsDeserializingBufferProvider::as_deserializing(buffer_provider),
+ ),
+ #[cfg(feature = "compiled_data")]
+ $crate::provider::ICU4XDataProviderInner::Compiled => $self.0.$compiled(),
+ }
+ };
+}
+
+#[diplomat::bridge]
+pub mod ffi {
+ use crate::errors::ffi::ICU4XError;
+ use crate::locale::ffi::ICU4XLocale;
+ use crate::provider::ffi::ICU4XDataProvider;
+ use crate::timezone::ffi::ICU4XCustomTimeZone;
+ use alloc::boxed::Box;
+ use icu_datetime::time_zone::FallbackFormat;
+ use icu_datetime::time_zone::IsoFormat;
+ use icu_datetime::time_zone::IsoMinutes;
+ use icu_datetime::time_zone::IsoSeconds;
+ use icu_datetime::time_zone::TimeZoneFormatter;
+ use writeable::Writeable;
+
+ #[diplomat::opaque]
+ /// An ICU4X TimeZoneFormatter object capable of formatting an [`ICU4XCustomTimeZone`] type (and others) as a string
+ #[diplomat::rust_link(icu::datetime::time_zone::TimeZoneFormatter, Struct)]
+ pub struct ICU4XTimeZoneFormatter(pub TimeZoneFormatter);
+
+ #[diplomat::enum_convert(IsoFormat, needs_wildcard)]
+ #[diplomat::rust_link(icu::datetime::time_zone::IsoFormat, Enum)]
+ pub enum ICU4XIsoTimeZoneFormat {
+ Basic,
+ Extended,
+ UtcBasic,
+ UtcExtended,
+ }
+
+ #[diplomat::enum_convert(IsoMinutes, needs_wildcard)]
+ #[diplomat::rust_link(icu::datetime::time_zone::IsoMinutes, Enum)]
+ pub enum ICU4XIsoTimeZoneMinuteDisplay {
+ Required,
+ Optional,
+ }
+
+ #[diplomat::enum_convert(IsoSeconds, needs_wildcard)]
+ #[diplomat::rust_link(icu::datetime::time_zone::IsoSeconds, Enum)]
+ pub enum ICU4XIsoTimeZoneSecondDisplay {
+ Optional,
+ Never,
+ }
+
+ pub struct ICU4XIsoTimeZoneOptions {
+ pub format: ICU4XIsoTimeZoneFormat,
+ pub minutes: ICU4XIsoTimeZoneMinuteDisplay,
+ pub seconds: ICU4XIsoTimeZoneSecondDisplay,
+ }
+
+ impl ICU4XTimeZoneFormatter {
+ /// Creates a new [`ICU4XTimeZoneFormatter`] from locale data.
+ ///
+ /// Uses localized GMT as the fallback format.
+ #[diplomat::rust_link(icu::datetime::time_zone::TimeZoneFormatter::try_new, FnInStruct)]
+ #[diplomat::rust_link(icu::datetime::time_zone::FallbackFormat, Enum, compact)]
+ #[diplomat::rust_link(icu::datetime::time_zone::TimeZoneFormatterOptions, Struct, hidden)]
+ pub fn create_with_localized_gmt_fallback(
+ provider: &ICU4XDataProvider,
+ locale: &ICU4XLocale,
+ ) -> Result<Box<ICU4XTimeZoneFormatter>, ICU4XError> {
+ let locale = locale.to_datalocale();
+
+ Ok(Box::new(ICU4XTimeZoneFormatter(call_constructor!(
+ TimeZoneFormatter::try_new,
+ TimeZoneFormatter::try_new_with_any_provider,
+ TimeZoneFormatter::try_new_with_buffer_provider,
+ provider,
+ &locale,
+ FallbackFormat::LocalizedGmt.into(),
+ )?)))
+ }
+
+ /// Creates a new [`ICU4XTimeZoneFormatter`] from locale data.
+ ///
+ /// Uses ISO-8601 as the fallback format.
+ #[diplomat::rust_link(icu::datetime::time_zone::TimeZoneFormatter::try_new, FnInStruct)]
+ #[diplomat::rust_link(icu::datetime::time_zone::FallbackFormat, Enum, compact)]
+ #[diplomat::rust_link(icu::datetime::time_zone::TimeZoneFormatterOptions, Struct, hidden)]
+ pub fn create_with_iso_8601_fallback(
+ provider: &ICU4XDataProvider,
+ locale: &ICU4XLocale,
+ options: ICU4XIsoTimeZoneOptions,
+ ) -> Result<Box<ICU4XTimeZoneFormatter>, ICU4XError> {
+ let locale = locale.to_datalocale();
+
+ Ok(Box::new(ICU4XTimeZoneFormatter(call_constructor!(
+ TimeZoneFormatter::try_new,
+ TimeZoneFormatter::try_new_with_any_provider,
+ TimeZoneFormatter::try_new_with_buffer_provider,
+ provider,
+ &locale,
+ options.into(),
+ )?)))
+ }
+
+ /// Loads generic non-location long format. Example: "Pacific Time"
+ #[diplomat::rust_link(
+ icu::datetime::time_zone::TimeZoneFormatter::include_generic_non_location_long,
+ FnInStruct
+ )]
+ #[diplomat::rust_link(
+ icu::datetime::time_zone::TimeZoneFormatter::load_generic_non_location_long,
+ FnInStruct,
+ hidden
+ )]
+ pub fn load_generic_non_location_long(
+ &mut self,
+ provider: &ICU4XDataProvider,
+ ) -> Result<(), ICU4XError> {
+ call_method!(
+ self,
+ include_generic_non_location_long,
+ load_generic_non_location_long,
+ provider
+ )?;
+ Ok(())
+ }
+
+ /// Loads generic non-location short format. Example: "PT"
+ #[diplomat::rust_link(
+ icu::datetime::time_zone::TimeZoneFormatter::include_generic_non_location_short,
+ FnInStruct
+ )]
+ #[diplomat::rust_link(
+ icu::datetime::time_zone::TimeZoneFormatter::load_generic_non_location_short,
+ FnInStruct,
+ hidden
+ )]
+ pub fn load_generic_non_location_short(
+ &mut self,
+ provider: &ICU4XDataProvider,
+ ) -> Result<(), ICU4XError> {
+ call_method!(
+ self,
+ include_generic_non_location_short,
+ load_generic_non_location_short,
+ provider
+ )?;
+ Ok(())
+ }
+
+ /// Loads specific non-location long format. Example: "Pacific Standard Time"
+ #[diplomat::rust_link(
+ icu::datetime::time_zone::TimeZoneFormatter::include_specific_non_location_long,
+ FnInStruct
+ )]
+ #[diplomat::rust_link(
+ icu::datetime::time_zone::TimeZoneFormatter::load_specific_non_location_long,
+ FnInStruct,
+ hidden
+ )]
+ pub fn load_specific_non_location_long(
+ &mut self,
+ provider: &ICU4XDataProvider,
+ ) -> Result<(), ICU4XError> {
+ call_method!(
+ self,
+ include_specific_non_location_long,
+ load_specific_non_location_long,
+ provider
+ )?;
+ Ok(())
+ }
+
+ /// Loads specific non-location short format. Example: "PST"
+ #[diplomat::rust_link(
+ icu::datetime::time_zone::TimeZoneFormatter::include_specific_non_location_short,
+ FnInStruct
+ )]
+ #[diplomat::rust_link(
+ icu::datetime::time_zone::TimeZoneFormatter::load_specific_non_location_short,
+ FnInStruct,
+ hidden
+ )]
+ pub fn load_specific_non_location_short(
+ &mut self,
+ provider: &ICU4XDataProvider,
+ ) -> Result<(), ICU4XError> {
+ call_method!(
+ self,
+ include_specific_non_location_short,
+ load_specific_non_location_short,
+ provider
+ )?;
+ Ok(())
+ }
+
+ /// Loads generic location format. Example: "Los Angeles Time"
+ #[diplomat::rust_link(
+ icu::datetime::time_zone::TimeZoneFormatter::include_generic_location_format,
+ FnInStruct
+ )]
+ #[diplomat::rust_link(
+ icu::datetime::time_zone::TimeZoneFormatter::load_generic_location_format,
+ FnInStruct,
+ hidden
+ )]
+ pub fn load_generic_location_format(
+ &mut self,
+ provider: &ICU4XDataProvider,
+ ) -> Result<(), ICU4XError> {
+ call_method!(
+ self,
+ include_generic_location_format,
+ load_generic_location_format,
+ provider
+ )?;
+ Ok(())
+ }
+
+ /// Loads localized GMT format. Example: "GMT-07:00"
+ #[diplomat::rust_link(
+ icu::datetime::time_zone::TimeZoneFormatter::include_localized_gmt_format,
+ FnInStruct
+ )]
+ #[diplomat::rust_link(
+ icu::datetime::time_zone::TimeZoneFormatter::load_localized_gmt_format,
+ FnInStruct,
+ hidden
+ )]
+ pub fn include_localized_gmt_format(&mut self) -> Result<(), ICU4XError> {
+ self.0.include_localized_gmt_format()?;
+ Ok(())
+ }
+
+ /// Loads ISO-8601 format. Example: "-07:00"
+ #[diplomat::rust_link(
+ icu::datetime::time_zone::TimeZoneFormatter::include_iso_8601_format,
+ FnInStruct
+ )]
+ #[diplomat::rust_link(
+ icu::datetime::time_zone::TimeZoneFormatter::load_iso_8601_format,
+ FnInStruct,
+ hidden
+ )]
+ pub fn load_iso_8601_format(
+ &mut self,
+ options: ICU4XIsoTimeZoneOptions,
+ ) -> Result<(), ICU4XError> {
+ self.0.include_iso_8601_format(
+ options.format.into(),
+ options.minutes.into(),
+ options.seconds.into(),
+ )?;
+ Ok(())
+ }
+
+ /// Formats a [`ICU4XCustomTimeZone`] to a string.
+ #[diplomat::rust_link(icu::datetime::time_zone::TimeZoneFormatter::format, FnInStruct)]
+ #[diplomat::rust_link(
+ icu::datetime::time_zone::TimeZoneFormatter::format_to_string,
+ FnInStruct
+ )]
+ pub fn format_custom_time_zone(
+ &self,
+ value: &ICU4XCustomTimeZone,
+ write: &mut diplomat_runtime::DiplomatWriteable,
+ ) -> Result<(), ICU4XError> {
+ self.0.format(&value.0).write_to(write)?;
+ Ok(())
+ }
+ }
+}
+
+impl From<ffi::ICU4XIsoTimeZoneOptions> for TimeZoneFormatterOptions {
+ fn from(other: ffi::ICU4XIsoTimeZoneOptions) -> Self {
+ FallbackFormat::Iso8601(
+ other.format.into(),
+ other.minutes.into(),
+ other.seconds.into(),
+ )
+ .into()
+ }
+}