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