Bug 1910110 - Return early when channel URI is void r=rpl a=Aryx
[gecko.git] / intl / icu_capi / src / timezone_formatter.rs
blob00ecb7b346f3193ddb34164b2d5354c01da5c358
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) => {
9         match &$provider.0 {
10             $crate::provider::ICU4XDataProviderInner::Destroyed => Err(
11                 icu_provider::DataError::custom("This provider has been destroyed"),
12             )?,
13             $crate::provider::ICU4XDataProviderInner::Empty => $self
14                 .0
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),
19             ),
20             #[cfg(feature = "compiled_data")]
21             $crate::provider::ICU4XDataProviderInner::Compiled => $self.0.$compiled(),
22         }
23     };
26 #[diplomat::bridge]
27 pub mod ffi {
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;
40     #[diplomat::opaque]
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 {
49         Basic,
50         Extended,
51         UtcBasic,
52         UtcExtended,
53     }
55     #[diplomat::enum_convert(IsoMinutes, needs_wildcard)]
56     #[diplomat::rust_link(icu::datetime::time_zone::IsoMinutes, Enum)]
57     pub enum ICU4XIsoTimeZoneMinuteDisplay {
58         Required,
59         Optional,
60     }
62     #[diplomat::enum_convert(IsoSeconds, needs_wildcard)]
63     #[diplomat::rust_link(icu::datetime::time_zone::IsoSeconds, Enum)]
64     pub enum ICU4XIsoTimeZoneSecondDisplay {
65         Optional,
66         Never,
67     }
69     pub struct ICU4XIsoTimeZoneOptions {
70         pub format: ICU4XIsoTimeZoneFormat,
71         pub minutes: ICU4XIsoTimeZoneMinuteDisplay,
72         pub seconds: ICU4XIsoTimeZoneSecondDisplay,
73     }
75     impl ICU4XTimeZoneFormatter {
76         /// Creates a new [`ICU4XTimeZoneFormatter`] from locale data.
77         ///
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,
85             locale: &ICU4XLocale,
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,
93                 provider,
94                 &locale,
95                 FallbackFormat::LocalizedGmt.into(),
96             )?)))
97         }
99         /// Creates a new [`ICU4XTimeZoneFormatter`] from locale data.
100         ///
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,
117                 provider,
118                 &locale,
119                 options.into(),
120             )?)))
121         }
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,
126             FnInStruct
127         )]
128         #[diplomat::rust_link(
129             icu::datetime::time_zone::TimeZoneFormatter::load_generic_non_location_long,
130             FnInStruct,
131             hidden
132         )]
133         pub fn load_generic_non_location_long(
134             &mut self,
135             provider: &ICU4XDataProvider,
136         ) -> Result<(), ICU4XError> {
137             call_method!(
138                 self,
139                 include_generic_non_location_long,
140                 load_generic_non_location_long,
141                 provider
142             )?;
143             Ok(())
144         }
146         /// Loads generic non-location short format. Example: "PT"
147         #[diplomat::rust_link(
148             icu::datetime::time_zone::TimeZoneFormatter::include_generic_non_location_short,
149             FnInStruct
150         )]
151         #[diplomat::rust_link(
152             icu::datetime::time_zone::TimeZoneFormatter::load_generic_non_location_short,
153             FnInStruct,
154             hidden
155         )]
156         pub fn load_generic_non_location_short(
157             &mut self,
158             provider: &ICU4XDataProvider,
159         ) -> Result<(), ICU4XError> {
160             call_method!(
161                 self,
162                 include_generic_non_location_short,
163                 load_generic_non_location_short,
164                 provider
165             )?;
166             Ok(())
167         }
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,
172             FnInStruct
173         )]
174         #[diplomat::rust_link(
175             icu::datetime::time_zone::TimeZoneFormatter::load_specific_non_location_long,
176             FnInStruct,
177             hidden
178         )]
179         pub fn load_specific_non_location_long(
180             &mut self,
181             provider: &ICU4XDataProvider,
182         ) -> Result<(), ICU4XError> {
183             call_method!(
184                 self,
185                 include_specific_non_location_long,
186                 load_specific_non_location_long,
187                 provider
188             )?;
189             Ok(())
190         }
192         /// Loads specific non-location short format. Example: "PST"
193         #[diplomat::rust_link(
194             icu::datetime::time_zone::TimeZoneFormatter::include_specific_non_location_short,
195             FnInStruct
196         )]
197         #[diplomat::rust_link(
198             icu::datetime::time_zone::TimeZoneFormatter::load_specific_non_location_short,
199             FnInStruct,
200             hidden
201         )]
202         pub fn load_specific_non_location_short(
203             &mut self,
204             provider: &ICU4XDataProvider,
205         ) -> Result<(), ICU4XError> {
206             call_method!(
207                 self,
208                 include_specific_non_location_short,
209                 load_specific_non_location_short,
210                 provider
211             )?;
212             Ok(())
213         }
215         /// Loads generic location format. Example: "Los Angeles Time"
216         #[diplomat::rust_link(
217             icu::datetime::time_zone::TimeZoneFormatter::include_generic_location_format,
218             FnInStruct
219         )]
220         #[diplomat::rust_link(
221             icu::datetime::time_zone::TimeZoneFormatter::load_generic_location_format,
222             FnInStruct,
223             hidden
224         )]
225         pub fn load_generic_location_format(
226             &mut self,
227             provider: &ICU4XDataProvider,
228         ) -> Result<(), ICU4XError> {
229             call_method!(
230                 self,
231                 include_generic_location_format,
232                 load_generic_location_format,
233                 provider
234             )?;
235             Ok(())
236         }
238         /// Loads localized GMT format. Example: "GMT-07:00"
239         #[diplomat::rust_link(
240             icu::datetime::time_zone::TimeZoneFormatter::include_localized_gmt_format,
241             FnInStruct
242         )]
243         #[diplomat::rust_link(
244             icu::datetime::time_zone::TimeZoneFormatter::load_localized_gmt_format,
245             FnInStruct,
246             hidden
247         )]
248         pub fn include_localized_gmt_format(&mut self) -> Result<(), ICU4XError> {
249             self.0.include_localized_gmt_format()?;
250             Ok(())
251         }
253         /// Loads ISO-8601 format. Example: "-07:00"
254         #[diplomat::rust_link(
255             icu::datetime::time_zone::TimeZoneFormatter::include_iso_8601_format,
256             FnInStruct
257         )]
258         #[diplomat::rust_link(
259             icu::datetime::time_zone::TimeZoneFormatter::load_iso_8601_format,
260             FnInStruct,
261             hidden
262         )]
263         pub fn load_iso_8601_format(
264             &mut self,
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(),
271             )?;
272             Ok(())
273         }
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,
279             FnInStruct
280         )]
281         #[diplomat::rust_link(icu::datetime::FormattedTimeZone::write_to, FnInStruct, hidden)]
282         pub fn format_custom_time_zone(
283             &self,
284             value: &ICU4XCustomTimeZone,
285             write: &mut diplomat_runtime::DiplomatWriteable,
286         ) -> Result<(), ICU4XError> {
287             self.0.format(&value.0).write_to(write)?;
288             Ok(())
289         }
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(
294             &self,
295             value: &ICU4XCustomTimeZone,
296             write: &mut diplomat_runtime::DiplomatWriteable,
297         ) -> Result<(), ICU4XError> {
298             self.0.format(&value.0).write_no_fallback(write)??;
299             Ok(())
300         }
301     }
304 impl From<ffi::ICU4XIsoTimeZoneOptions> for TimeZoneFormatterOptions {
305     fn from(other: ffi::ICU4XIsoTimeZoneOptions) -> Self {
306         FallbackFormat::Iso8601(
307             other.format.into(),
308             other.minutes.into(),
309             other.seconds.into(),
310         )
311         .into()
312     }