• 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 alloc::sync::Arc;
11     use icu_datetime::fieldsets::{T, YMD};
12     #[cfg(any(feature = "compiled_data", feature = "buffer_provider"))]
13     use icu_datetime::options::Length;
14 
15     #[cfg(any(feature = "compiled_data", feature = "buffer_provider"))]
16     use crate::errors::ffi::DateTimeFormatterLoadError;
17     #[cfg(any(feature = "compiled_data", feature = "buffer_provider"))]
18     use crate::locale_core::ffi::Locale;
19     #[cfg(feature = "buffer_provider")]
20     use crate::provider::ffi::DataProvider;
21     use crate::{
22         calendar::ffi::Calendar,
23         date::ffi::{Date, IsoDate},
24         errors::ffi::DateTimeFormatError,
25         time::ffi::Time,
26     };
27 
28     use writeable::Writeable;
29 
30     #[diplomat::opaque]
31     /// An ICU4X NoCalendarFormatter object capable of formatting an [`Time`] type (and others) as a string
32     #[diplomat::rust_link(icu::datetime::NoCalendarFormatter, Typedef)]
33     #[diplomat::rust_link(icu::datetime::fieldsets::T, Struct, compact)]
34     pub struct NoCalendarFormatter(pub icu_datetime::NoCalendarFormatter<T>);
35 
36     #[diplomat::enum_convert(icu_datetime::options::Length, needs_wildcard)]
37     #[diplomat::rust_link(icu::datetime::Length, Enum)]
38     pub enum DateTimeLength {
39         Long,
40         Medium,
41         Short,
42     }
43 
44     impl NoCalendarFormatter {
45         /// Creates a new [`NoCalendarFormatter`] using compiled data.
46         #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "with_length")]
47         #[diplomat::demo(default_constructor)]
48         #[cfg(feature = "compiled_data")]
49         #[diplomat::rust_link(icu::datetime::FixedCalendarDateTimeFormatter::try_new, FnInStruct)]
create_with_length( locale: &Locale, length: DateTimeLength, ) -> Result<Box<NoCalendarFormatter>, DateTimeFormatterLoadError>50         pub fn create_with_length(
51             locale: &Locale,
52             length: DateTimeLength,
53         ) -> Result<Box<NoCalendarFormatter>, DateTimeFormatterLoadError> {
54             let prefs = (&locale.0).into();
55             let options = T::with_length(Length::from(length)).hm();
56 
57             Ok(Box::new(NoCalendarFormatter(
58                 icu_datetime::FixedCalendarDateTimeFormatter::try_new(prefs, options)?,
59             )))
60         }
61 
62         /// Creates a new [`NoCalendarFormatter`] using a particular data source.
63         #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "with_length_and_provider")]
64         #[cfg(feature = "buffer_provider")]
65         #[diplomat::rust_link(icu::datetime::FixedCalendarDateTimeFormatter::try_new, FnInStruct)]
create_with_length_and_provider( provider: &DataProvider, locale: &Locale, length: DateTimeLength, ) -> Result<Box<NoCalendarFormatter>, DateTimeFormatterLoadError>66         pub fn create_with_length_and_provider(
67             provider: &DataProvider,
68             locale: &Locale,
69             length: DateTimeLength,
70         ) -> Result<Box<NoCalendarFormatter>, DateTimeFormatterLoadError> {
71             let prefs = (&locale.0).into();
72             let options = T::with_length(Length::from(length)).hm();
73 
74             Ok(Box::new(NoCalendarFormatter(
75                 icu_datetime::FixedCalendarDateTimeFormatter::try_new_with_buffer_provider(
76                     provider.get()?,
77                     prefs,
78                     options,
79                 )?,
80             )))
81         }
82 
83         /// Formats a [`Time`] to a string.
84         #[diplomat::rust_link(icu::datetime::FixedCalendarDateTimeFormatter::format, FnInStruct)]
85         #[diplomat::rust_link(icu::datetime::FormattedDateTime, Struct, hidden)]
format(&self, value: &Time, write: &mut diplomat_runtime::DiplomatWrite)86         pub fn format(&self, value: &Time, write: &mut diplomat_runtime::DiplomatWrite) {
87             let _infallible = self.0.format(&value.0).write_to(write);
88         }
89     }
90 
91     #[diplomat::opaque]
92     /// An ICU4X TypedDateFormatter object capable of formatting an [`IsoDate`] and a [`Time`] as a string,
93     /// using the Gregorian Calendar.
94     #[diplomat::rust_link(icu::datetime::FixedCalendarDateTimeFormatter, Struct)]
95     #[diplomat::rust_link(icu::datetime::fieldsets::YMD, Struct, compact)]
96     pub struct GregorianDateFormatter(
97         pub icu_datetime::FixedCalendarDateTimeFormatter<icu_calendar::Gregorian, YMD>,
98     );
99 
100     impl GregorianDateFormatter {
101         /// Creates a new [`GregorianDateFormatter`] using compiled data.
102         #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "with_length")]
103         #[diplomat::demo(default_constructor)]
104         #[cfg(feature = "compiled_data")]
105         #[diplomat::rust_link(icu::datetime::FixedCalendarDateTimeFormatter::try_new, FnInStruct)]
create_with_length( locale: &Locale, length: DateTimeLength, ) -> Result<Box<GregorianDateFormatter>, DateTimeFormatterLoadError>106         pub fn create_with_length(
107             locale: &Locale,
108             length: DateTimeLength,
109         ) -> Result<Box<GregorianDateFormatter>, DateTimeFormatterLoadError> {
110             let prefs = (&locale.0).into();
111             let options = YMD::with_length(Length::from(length));
112 
113             Ok(Box::new(GregorianDateFormatter(
114                 icu_datetime::FixedCalendarDateTimeFormatter::try_new(prefs, options)?,
115             )))
116         }
117 
118         /// Creates a new [`GregorianDateFormatter`] using a particular data source.
119         #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "with_length_and_provider")]
120         #[cfg(feature = "buffer_provider")]
121         #[diplomat::rust_link(icu::datetime::FixedCalendarDateTimeFormatter::try_new, FnInStruct)]
create_with_length_and_provider( provider: &DataProvider, locale: &Locale, length: DateTimeLength, ) -> Result<Box<GregorianDateFormatter>, DateTimeFormatterLoadError>122         pub fn create_with_length_and_provider(
123             provider: &DataProvider,
124             locale: &Locale,
125             length: DateTimeLength,
126         ) -> Result<Box<GregorianDateFormatter>, DateTimeFormatterLoadError> {
127             let prefs = (&locale.0).into();
128             let options = YMD::with_length(Length::from(length));
129 
130             Ok(Box::new(GregorianDateFormatter(
131                 icu_datetime::FixedCalendarDateTimeFormatter::try_new_with_buffer_provider(
132                     provider.get()?,
133                     prefs,
134                     options,
135                 )?,
136             )))
137         }
138 
139         /// Formats a [`IsoDate`] to a string.
140         #[diplomat::rust_link(icu::datetime::FixedCalendarDateTimeFormatter::format, FnInStruct)]
141         #[diplomat::rust_link(icu::datetime::FormattedDateTime, Struct, hidden)]
format_iso(&self, value: &IsoDate, write: &mut diplomat_runtime::DiplomatWrite)142         pub fn format_iso(&self, value: &IsoDate, write: &mut diplomat_runtime::DiplomatWrite) {
143             let greg = icu_calendar::Date::new_from_iso(value.0, icu_calendar::Gregorian);
144             let _infallible = self.0.format(&greg).write_to(write);
145         }
146     }
147 
148     #[diplomat::opaque]
149     /// An ICU4X DateFormatter object capable of formatting a [`Date`] as a string,
150     /// using some calendar specified at runtime in the locale.
151     #[diplomat::rust_link(icu::datetime::DateTimeFormatter, Struct)]
152     #[diplomat::rust_link(icu::datetime::fieldsets::YMD, Struct, compact)]
153     pub struct DateFormatter(pub icu_datetime::DateTimeFormatter<YMD>);
154 
155     impl DateFormatter {
156         /// Creates a new [`DateFormatter`] using compiled data.
157         #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "with_length")]
158         #[diplomat::demo(default_constructor)]
159         #[cfg(feature = "compiled_data")]
160         #[diplomat::rust_link(icu::datetime::DateTimeFormatter::try_new, FnInStruct)]
create_with_length( locale: &Locale, length: DateTimeLength, ) -> Result<Box<DateFormatter>, DateTimeFormatterLoadError>161         pub fn create_with_length(
162             locale: &Locale,
163             length: DateTimeLength,
164         ) -> Result<Box<DateFormatter>, DateTimeFormatterLoadError> {
165             let prefs = (&locale.0).into();
166             let options = YMD::with_length(Length::from(length));
167 
168             Ok(Box::new(DateFormatter(
169                 icu_datetime::DateTimeFormatter::try_new(prefs, options)?,
170             )))
171         }
172 
173         /// Creates a new [`DateFormatter`] using a particular data source.
174         #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "with_length_and_provider")]
175         #[cfg(feature = "buffer_provider")]
176         #[diplomat::rust_link(icu::datetime::DateTimeFormatter::try_new, FnInStruct)]
create_with_length_and_provider( provider: &DataProvider, locale: &Locale, length: DateTimeLength, ) -> Result<Box<DateFormatter>, DateTimeFormatterLoadError>177         pub fn create_with_length_and_provider(
178             provider: &DataProvider,
179             locale: &Locale,
180             length: DateTimeLength,
181         ) -> Result<Box<DateFormatter>, DateTimeFormatterLoadError> {
182             let prefs = (&locale.0).into();
183             let options = YMD::with_length(Length::from(length));
184 
185             Ok(Box::new(DateFormatter(
186                 icu_datetime::DateTimeFormatter::try_new_with_buffer_provider(
187                     provider.get()?,
188                     prefs,
189                     options,
190                 )?,
191             )))
192         }
193 
194         /// Formats a [`Date`] to a string.
195         #[diplomat::rust_link(icu::datetime::DateTimeFormatter::format, FnInStruct)]
196         #[diplomat::rust_link(icu::datetime::FormattedDateTime, Struct, hidden)]
format( &self, value: &Date, write: &mut diplomat_runtime::DiplomatWrite, ) -> Result<(), DateTimeFormatError>197         pub fn format(
198             &self,
199             value: &Date,
200             write: &mut diplomat_runtime::DiplomatWrite,
201         ) -> Result<(), DateTimeFormatError> {
202             let _infallible = self.0.format(&value.0).write_to(write);
203             Ok(())
204         }
205 
206         /// Formats a [`IsoDate`] to a string.
207         ///
208         /// Will convert to this formatter's calendar first
209         #[diplomat::rust_link(icu::datetime::DateTimeFormatter::format, FnInStruct)]
210         #[diplomat::rust_link(icu::datetime::FormattedDateTime, Struct, hidden)]
format_iso( &self, value: &IsoDate, write: &mut diplomat_runtime::DiplomatWrite, ) -> Result<(), DateTimeFormatError>211         pub fn format_iso(
212             &self,
213             value: &IsoDate,
214             write: &mut diplomat_runtime::DiplomatWrite,
215         ) -> Result<(), DateTimeFormatError> {
216             let any = value.0.to_any();
217             let _infallible = self.0.format(&any).write_to(write);
218             Ok(())
219         }
220 
221         /// Returns the calendar system used in this formatter.
222         #[diplomat::rust_link(icu::datetime::DateTimeFormatter::calendar, FnInStruct)]
calendar(&self) -> Box<Calendar>223         pub fn calendar(&self) -> Box<Calendar> {
224             Box::new(Calendar(Arc::new(self.0.calendar().0.clone())))
225         }
226     }
227 }
228