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 ).
5 use icu_datetime::time_zone::{FallbackFormat, TimeZoneFormatterOptions};
7 macro_rules! call_method {
8 ($self:ident, $compiled:ident, $unstable:ident, $provider:expr) => {
10 $crate::provider::ICU4XDataProviderInner::Destroyed => Err(
11 icu_provider::DataError::custom("This provider has been destroyed"),
13 $crate::provider::ICU4XDataProviderInner::Empty => $self
15 .$unstable(&icu_provider_adapters::empty::EmptyDataProvider::new()),
16 #[cfg(feature = "buffer_provider")]
17 $crate::provider::ICU4XDataProviderInner::Buffer(buffer_provider) => $self.0.$unstable(
18 &icu_provider::AsDeserializingBufferProvider::as_deserializing(buffer_provider),
20 #[cfg(feature = "compiled_data")]
21 $crate::provider::ICU4XDataProviderInner::Compiled => $self.0.$compiled(),
28 use crate::errors::ffi::ICU4XError;
29 use crate::locale::ffi::ICU4XLocale;
30 use crate::provider::ffi::ICU4XDataProvider;
31 use crate::timezone::ffi::ICU4XCustomTimeZone;
32 use alloc::boxed::Box;
33 use icu_datetime::time_zone::FallbackFormat;
34 use icu_datetime::time_zone::IsoFormat;
35 use icu_datetime::time_zone::IsoMinutes;
36 use icu_datetime::time_zone::IsoSeconds;
37 use icu_datetime::time_zone::TimeZoneFormatter;
38 use writeable::Writeable;
41 /// An ICU4X TimeZoneFormatter object capable of formatting an [`ICU4XCustomTimeZone`] type (and others) as a string
42 #[diplomat::rust_link(icu::datetime::time_zone::TimeZoneFormatter, Struct)]
43 #[diplomat::rust_link(icu::datetime::FormattedTimeZone, Struct, hidden)]
44 pub struct ICU4XTimeZoneFormatter(pub TimeZoneFormatter);
46 #[diplomat::enum_convert(IsoFormat, needs_wildcard)]
47 #[diplomat::rust_link(icu::datetime::time_zone::IsoFormat, Enum)]
48 pub enum ICU4XIsoTimeZoneFormat {
55 #[diplomat::enum_convert(IsoMinutes, needs_wildcard)]
56 #[diplomat::rust_link(icu::datetime::time_zone::IsoMinutes, Enum)]
57 pub enum ICU4XIsoTimeZoneMinuteDisplay {
62 #[diplomat::enum_convert(IsoSeconds, needs_wildcard)]
63 #[diplomat::rust_link(icu::datetime::time_zone::IsoSeconds, Enum)]
64 pub enum ICU4XIsoTimeZoneSecondDisplay {
69 pub struct ICU4XIsoTimeZoneOptions {
70 pub format: ICU4XIsoTimeZoneFormat,
71 pub minutes: ICU4XIsoTimeZoneMinuteDisplay,
72 pub seconds: ICU4XIsoTimeZoneSecondDisplay,
75 impl ICU4XTimeZoneFormatter {
76 /// Creates a new [`ICU4XTimeZoneFormatter`] from locale data.
78 /// Uses localized GMT as the fallback format.
79 #[diplomat::rust_link(icu::datetime::time_zone::TimeZoneFormatter::try_new, FnInStruct)]
80 #[diplomat::rust_link(icu::datetime::time_zone::FallbackFormat, Enum, compact)]
81 #[diplomat::rust_link(icu::datetime::time_zone::TimeZoneFormatterOptions, Struct, hidden)]
82 #[diplomat::attr(all(supports = constructors, supports = fallible_constructors, supports = named_constructors), named_constructor = "with_localized_gmt_fallback")]
83 pub fn create_with_localized_gmt_fallback(
84 provider: &ICU4XDataProvider,
86 ) -> Result<Box<ICU4XTimeZoneFormatter>, ICU4XError> {
87 let locale = locale.to_datalocale();
89 Ok(Box::new(ICU4XTimeZoneFormatter(call_constructor!(
90 TimeZoneFormatter::try_new,
91 TimeZoneFormatter::try_new_with_any_provider,
92 TimeZoneFormatter::try_new_with_buffer_provider,
95 FallbackFormat::LocalizedGmt.into(),
99 /// Creates a new [`ICU4XTimeZoneFormatter`] from locale data.
101 /// Uses ISO-8601 as the fallback format.
102 #[diplomat::rust_link(icu::datetime::time_zone::TimeZoneFormatter::try_new, FnInStruct)]
103 #[diplomat::rust_link(icu::datetime::time_zone::FallbackFormat, Enum, compact)]
104 #[diplomat::rust_link(icu::datetime::time_zone::TimeZoneFormatterOptions, Struct, hidden)]
105 #[diplomat::attr(all(supports = constructors, supports = fallible_constructors, supports = named_constructors), named_constructor = "with_iso_8601_fallback")]
106 pub fn create_with_iso_8601_fallback(
107 provider: &ICU4XDataProvider,
108 locale: &ICU4XLocale,
109 options: ICU4XIsoTimeZoneOptions,
110 ) -> Result<Box<ICU4XTimeZoneFormatter>, ICU4XError> {
111 let locale = locale.to_datalocale();
113 Ok(Box::new(ICU4XTimeZoneFormatter(call_constructor!(
114 TimeZoneFormatter::try_new,
115 TimeZoneFormatter::try_new_with_any_provider,
116 TimeZoneFormatter::try_new_with_buffer_provider,
123 /// Loads generic non-location long format. Example: "Pacific Time"
124 #[diplomat::rust_link(
125 icu::datetime::time_zone::TimeZoneFormatter::include_generic_non_location_long,
128 #[diplomat::rust_link(
129 icu::datetime::time_zone::TimeZoneFormatter::load_generic_non_location_long,
133 pub fn load_generic_non_location_long(
135 provider: &ICU4XDataProvider,
136 ) -> Result<(), ICU4XError> {
139 include_generic_non_location_long,
140 load_generic_non_location_long,
146 /// Loads generic non-location short format. Example: "PT"
147 #[diplomat::rust_link(
148 icu::datetime::time_zone::TimeZoneFormatter::include_generic_non_location_short,
151 #[diplomat::rust_link(
152 icu::datetime::time_zone::TimeZoneFormatter::load_generic_non_location_short,
156 pub fn load_generic_non_location_short(
158 provider: &ICU4XDataProvider,
159 ) -> Result<(), ICU4XError> {
162 include_generic_non_location_short,
163 load_generic_non_location_short,
169 /// Loads specific non-location long format. Example: "Pacific Standard Time"
170 #[diplomat::rust_link(
171 icu::datetime::time_zone::TimeZoneFormatter::include_specific_non_location_long,
174 #[diplomat::rust_link(
175 icu::datetime::time_zone::TimeZoneFormatter::load_specific_non_location_long,
179 pub fn load_specific_non_location_long(
181 provider: &ICU4XDataProvider,
182 ) -> Result<(), ICU4XError> {
185 include_specific_non_location_long,
186 load_specific_non_location_long,
192 /// Loads specific non-location short format. Example: "PST"
193 #[diplomat::rust_link(
194 icu::datetime::time_zone::TimeZoneFormatter::include_specific_non_location_short,
197 #[diplomat::rust_link(
198 icu::datetime::time_zone::TimeZoneFormatter::load_specific_non_location_short,
202 pub fn load_specific_non_location_short(
204 provider: &ICU4XDataProvider,
205 ) -> Result<(), ICU4XError> {
208 include_specific_non_location_short,
209 load_specific_non_location_short,
215 /// Loads generic location format. Example: "Los Angeles Time"
216 #[diplomat::rust_link(
217 icu::datetime::time_zone::TimeZoneFormatter::include_generic_location_format,
220 #[diplomat::rust_link(
221 icu::datetime::time_zone::TimeZoneFormatter::load_generic_location_format,
225 pub fn load_generic_location_format(
227 provider: &ICU4XDataProvider,
228 ) -> Result<(), ICU4XError> {
231 include_generic_location_format,
232 load_generic_location_format,
238 /// Loads localized GMT format. Example: "GMT-07:00"
239 #[diplomat::rust_link(
240 icu::datetime::time_zone::TimeZoneFormatter::include_localized_gmt_format,
243 #[diplomat::rust_link(
244 icu::datetime::time_zone::TimeZoneFormatter::load_localized_gmt_format,
248 pub fn include_localized_gmt_format(&mut self) -> Result<(), ICU4XError> {
249 self.0.include_localized_gmt_format()?;
253 /// Loads ISO-8601 format. Example: "-07:00"
254 #[diplomat::rust_link(
255 icu::datetime::time_zone::TimeZoneFormatter::include_iso_8601_format,
258 #[diplomat::rust_link(
259 icu::datetime::time_zone::TimeZoneFormatter::load_iso_8601_format,
263 pub fn load_iso_8601_format(
265 options: ICU4XIsoTimeZoneOptions,
266 ) -> Result<(), ICU4XError> {
267 self.0.include_iso_8601_format(
268 options.format.into(),
269 options.minutes.into(),
270 options.seconds.into(),
275 /// Formats a [`ICU4XCustomTimeZone`] to a string.
276 #[diplomat::rust_link(icu::datetime::time_zone::TimeZoneFormatter::format, FnInStruct)]
277 #[diplomat::rust_link(
278 icu::datetime::time_zone::TimeZoneFormatter::format_to_string,
281 #[diplomat::rust_link(icu::datetime::FormattedTimeZone::write_to, FnInStruct, hidden)]
282 pub fn format_custom_time_zone(
284 value: &ICU4XCustomTimeZone,
285 write: &mut diplomat_runtime::DiplomatWriteable,
286 ) -> Result<(), ICU4XError> {
287 self.0.format(&value.0).write_to(write)?;
291 /// Formats a [`ICU4XCustomTimeZone`] to a string, performing no fallback
292 #[diplomat::rust_link(icu::datetime::FormattedTimeZone::write_no_fallback, FnInStruct)]
293 pub fn format_custom_time_zone_no_fallback(
295 value: &ICU4XCustomTimeZone,
296 write: &mut diplomat_runtime::DiplomatWriteable,
297 ) -> Result<(), ICU4XError> {
298 self.0.format(&value.0).write_no_fallback(write)??;
304 impl From<ffi::ICU4XIsoTimeZoneOptions> for TimeZoneFormatterOptions {
305 fn from(other: ffi::ICU4XIsoTimeZoneOptions) -> Self {
306 FallbackFormat::Iso8601(
308 other.minutes.into(),
309 other.seconds.into(),