• 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 icu_datetime::fieldsets::{zone::GenericShort, Combo, YMDT};
11     #[cfg(any(feature = "compiled_data", feature = "buffer_provider"))]
12     use icu_datetime::options::Length;
13 
14     #[cfg(feature = "buffer_provider")]
15     use crate::provider::ffi::DataProvider;
16     use crate::{
17         date::ffi::{Date, IsoDate},
18         errors::ffi::DateTimeFormatError,
19         time::ffi::Time,
20         timezone::ffi::TimeZoneInfo,
21     };
22 
23     #[cfg(any(feature = "compiled_data", feature = "buffer_provider"))]
24     use crate::{
25         datetime_formatter::ffi::DateTimeLength, errors::ffi::DateTimeFormatterLoadError,
26         locale_core::ffi::Locale,
27     };
28 
29     use writeable::Writeable;
30 
31     #[diplomat::opaque]
32     /// An object capable of formatting a date time with time zone to a string.
33     #[diplomat::rust_link(icu::datetime::FixedCalendarDateTimeFormatter, Struct)]
34     #[diplomat::rust_link(icu::datetime::fieldsets::YMDT, Struct, compact)]
35     #[diplomat::rust_link(icu::datetime::fieldsets::zone::GenericShort, Struct, compact)]
36     pub struct GregorianZonedDateTimeFormatter(
37         pub  icu_datetime::FixedCalendarDateTimeFormatter<
38             icu_calendar::Gregorian,
39             Combo<YMDT, GenericShort>,
40         >,
41     );
42 
43     impl GregorianZonedDateTimeFormatter {
44         /// Creates a new [`GregorianZonedDateTimeFormatter`] from locale data using compiled data.
45         ///
46         /// This function has `date_length` and `time_length` arguments and uses default options
47         /// for the time zone.
48         #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "with_length")]
49         #[diplomat::demo(default_constructor)]
50         #[cfg(feature = "compiled_data")]
51         #[diplomat::rust_link(icu::datetime::FixedCalendarDateTimeFormatter::try_new, FnInStruct)]
create_with_length( locale: &Locale, length: DateTimeLength, ) -> Result<Box<GregorianZonedDateTimeFormatter>, DateTimeFormatterLoadError>52         pub fn create_with_length(
53             locale: &Locale,
54             length: DateTimeLength,
55         ) -> Result<Box<GregorianZonedDateTimeFormatter>, DateTimeFormatterLoadError> {
56             let prefs = (&locale.0).into();
57             let options = YMDT::with_length(Length::from(length)).zone(GenericShort);
58 
59             Ok(Box::new(GregorianZonedDateTimeFormatter(
60                 icu_datetime::FixedCalendarDateTimeFormatter::try_new(prefs, options)?,
61             )))
62         }
63         /// Creates a new [`GregorianZonedDateTimeFormatter`] from locale data using a particular data source.
64         ///
65         /// This function has `date_length` and `time_length` arguments and uses default options
66         /// for the time zone.
67         #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "with_length_and_provider")]
68         #[cfg(feature = "buffer_provider")]
69         #[diplomat::rust_link(icu::datetime::FixedCalendarDateTimeFormatter::try_new, FnInStruct)]
create_with_length_and_provider( provider: &DataProvider, locale: &Locale, length: DateTimeLength, ) -> Result<Box<GregorianZonedDateTimeFormatter>, DateTimeFormatterLoadError>70         pub fn create_with_length_and_provider(
71             provider: &DataProvider,
72             locale: &Locale,
73             length: DateTimeLength,
74         ) -> Result<Box<GregorianZonedDateTimeFormatter>, DateTimeFormatterLoadError> {
75             let prefs = (&locale.0).into();
76             let options = YMDT::with_length(Length::from(length)).zone(GenericShort);
77 
78             Ok(Box::new(GregorianZonedDateTimeFormatter(
79                 icu_datetime::FixedCalendarDateTimeFormatter::try_new_with_buffer_provider(
80                     provider.get()?,
81                     prefs,
82                     options,
83                 )?,
84             )))
85         }
86         /// Formats an [`IsoDate`] a [`Time`], and a [`TimeZoneInfo`] to a string.
87         #[diplomat::rust_link(icu::datetime::FixedCalendarDateTimeFormatter::format, FnInStruct)]
88         #[diplomat::rust_link(icu::datetime::FormattedDateTime, Struct, hidden)]
format_iso( &self, date: &IsoDate, time: &Time, zone: &TimeZoneInfo, write: &mut diplomat_runtime::DiplomatWrite, ) -> Result<(), DateTimeFormatError>89         pub fn format_iso(
90             &self,
91             date: &IsoDate,
92             time: &Time,
93             zone: &TimeZoneInfo,
94             write: &mut diplomat_runtime::DiplomatWrite,
95         ) -> Result<(), DateTimeFormatError> {
96             let zdt = icu_time::ZonedDateTime {
97                 date: icu_calendar::Date::new_from_iso(date.0, icu_calendar::Gregorian),
98                 time: time.0,
99                 zone: zone
100                     .time_zone_id
101                     .with_offset(zone.offset)
102                     .at_time((date.0, time.0))
103                     .with_zone_variant(
104                         zone.zone_variant
105                             .ok_or(DateTimeFormatError::ZoneInfoMissingFields)?,
106                     ),
107             };
108             let _infallible = self.0.format(&zdt).write_to(write);
109             Ok(())
110         }
111     }
112 
113     #[diplomat::opaque]
114     /// An object capable of formatting a date time with time zone to a string.
115     #[diplomat::rust_link(icu::datetime::DateTimeFormatter, Struct)]
116     #[diplomat::rust_link(icu::datetime::fieldsets::YMDT, Struct, compact)]
117     #[diplomat::rust_link(icu::datetime::fieldsets::zone::GenericShort, Struct, compact)]
118     pub struct ZonedDateTimeFormatter(
119         pub icu_datetime::DateTimeFormatter<Combo<YMDT, GenericShort>>,
120     );
121 
122     impl ZonedDateTimeFormatter {
123         /// Creates a new [`ZonedDateTimeFormatter`] from locale data using compiled data.
124         ///
125         /// This function has `date_length` and `time_length` arguments and uses default options
126         /// for the time zone.
127         #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "with_length")]
128         #[diplomat::demo(default_constructor)]
129         #[cfg(feature = "compiled_data")]
130         #[diplomat::rust_link(icu::datetime::DateTimeFormatter::try_new, FnInStruct)]
create_with_length( locale: &Locale, length: DateTimeLength, ) -> Result<Box<ZonedDateTimeFormatter>, DateTimeFormatterLoadError>131         pub fn create_with_length(
132             locale: &Locale,
133             length: DateTimeLength,
134         ) -> Result<Box<ZonedDateTimeFormatter>, DateTimeFormatterLoadError> {
135             let prefs = (&locale.0).into();
136             let options = YMDT::with_length(Length::from(length)).zone(GenericShort);
137 
138             Ok(Box::new(ZonedDateTimeFormatter(
139                 icu_datetime::DateTimeFormatter::try_new(prefs, options)?,
140             )))
141         }
142         /// Creates a new [`ZonedDateTimeFormatter`] from locale data using a particular data source.
143         ///
144         /// This function has `date_length` and `time_length` arguments and uses default options
145         /// for the time zone.
146         #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "with_length_and_provider")]
147         #[cfg(feature = "buffer_provider")]
148         #[diplomat::rust_link(icu::datetime::DateTimeFormatter::try_new, FnInStruct)]
create_with_length_and_provider( provider: &DataProvider, locale: &Locale, length: DateTimeLength, ) -> Result<Box<ZonedDateTimeFormatter>, DateTimeFormatterLoadError>149         pub fn create_with_length_and_provider(
150             provider: &DataProvider,
151             locale: &Locale,
152             length: DateTimeLength,
153         ) -> Result<Box<ZonedDateTimeFormatter>, DateTimeFormatterLoadError> {
154             let prefs = (&locale.0).into();
155             let options = YMDT::with_length(Length::from(length)).zone(GenericShort);
156 
157             Ok(Box::new(ZonedDateTimeFormatter(
158                 icu_datetime::DateTimeFormatter::try_new_with_buffer_provider(
159                     provider.get()?,
160                     prefs,
161                     options,
162                 )?,
163             )))
164         }
165         /// Formats a [`Date`] a [`Time`], and a [`TimeZoneInfo`] to a string.
166         #[diplomat::rust_link(icu::datetime::DateTimeFormatter::format, FnInStruct)]
167         #[diplomat::rust_link(icu::datetime::FormattedDateTime, Struct, hidden)]
format( &self, date: &Date, time: &Time, zone: &TimeZoneInfo, write: &mut diplomat_runtime::DiplomatWrite, ) -> Result<(), DateTimeFormatError>168         pub fn format(
169             &self,
170             date: &Date,
171             time: &Time,
172             zone: &TimeZoneInfo,
173             write: &mut diplomat_runtime::DiplomatWrite,
174         ) -> Result<(), DateTimeFormatError> {
175             let zdt = icu_time::ZonedDateTime {
176                 date: date.0.wrap_calendar_in_ref(),
177                 time: time.0,
178                 zone: zone
179                     .time_zone_id
180                     .with_offset(zone.offset)
181                     .at_time((date.0.to_iso(), time.0))
182                     .with_zone_variant(
183                         zone.zone_variant
184                             .ok_or(DateTimeFormatError::ZoneInfoMissingFields)?,
185                     ),
186             };
187             let _infallible = self.0.format(&zdt).write_to(write);
188             Ok(())
189         }
190 
191         /// Formats an [`IsoDate`] a [`Time`], and a [`TimeZoneInfo`] to a string.
192         #[diplomat::rust_link(icu::datetime::DateTimeFormatter::format, FnInStruct)]
193         #[diplomat::rust_link(icu::datetime::FormattedDateTime, Struct, hidden)]
format_iso( &self, date: &IsoDate, time: &Time, zone: &TimeZoneInfo, write: &mut diplomat_runtime::DiplomatWrite, ) -> Result<(), DateTimeFormatError>194         pub fn format_iso(
195             &self,
196             date: &IsoDate,
197             time: &Time,
198             zone: &TimeZoneInfo,
199             write: &mut diplomat_runtime::DiplomatWrite,
200         ) -> Result<(), DateTimeFormatError> {
201             let zdt = icu_time::ZonedDateTime {
202                 date: date.0,
203                 time: time.0,
204                 zone: zone
205                     .time_zone_id
206                     .with_offset(zone.offset)
207                     .at_time((date.0, time.0))
208                     .with_zone_variant(
209                         zone.zone_variant
210                             .ok_or(DateTimeFormatError::ZoneInfoMissingFields)?,
211                     ),
212             };
213             let _infallible = self.0.format(&zdt).write_to(write);
214             Ok(())
215         }
216     }
217 }
218