From 36d97cd02a65070c58e20795c8848afe620e617f Mon Sep 17 00:00:00 2001 From: Zibi Braniecki Date: Thu, 14 Nov 2024 22:59:20 -0800 Subject: [PATCH] Migrate decimal and experimental to Preferences (#5803) Migrated experimental formatters to Preferences --- components/datetime/src/external_loaders.rs | 12 +- components/datetime/src/format/datetime.rs | 2 +- components/decimal/README.md | 6 +- .../decimal/benches/fixed_decimal_format.rs | 2 +- components/decimal/examples/code_line_diff.rs | 2 +- components/decimal/src/format.rs | 2 +- components/decimal/src/grouper.rs | 2 +- components/decimal/src/lib.rs | 36 ++++-- components/decimal/src/options.rs | 2 +- .../experimental/src/compactdecimal/format.rs | 2 +- .../src/compactdecimal/formatter.rs | 106 +++++++++++------- .../src/dimension/currency/format.rs | 6 +- .../src/dimension/currency/formatter.rs | 47 ++++++-- .../src/dimension/currency/long_format.rs | 6 +- .../src/dimension/currency/long_formatter.rs | 37 +++--- .../src/dimension/percent/format.rs | 26 ++--- .../src/dimension/percent/formatter.rs | 51 ++++++--- .../src/dimension/units/format.rs | 2 +- .../src/dimension/units/formatter.rs | 49 +++++--- .../experimental/src/duration/format.rs | 8 +- .../experimental/src/duration/formatter.rs | 71 ++++++++---- .../src/relativetime/relativetime.rs | 42 ++++--- .../experimental/tests/relativetime/tests.rs | 4 +- .../unicode/keywords/numbering_system.rs | 2 + .../unicode/keywords/regional_subdivision.rs | 10 -- .../unicode/macros/struct_keyword.rs | 8 ++ components/locale_core/src/preferences/mod.rs | 41 +++++++ ffi/capi/src/decimal.rs | 7 +- ffi/capi/tests/missing_apis.txt | 2 + tutorials/data_provider.md | 4 +- 30 files changed, 407 insertions(+), 190 deletions(-) diff --git a/components/datetime/src/external_loaders.rs b/components/datetime/src/external_loaders.rs index 53e5c060f0c..b7198e974d4 100644 --- a/components/datetime/src/external_loaders.rs +++ b/components/datetime/src/external_loaders.rs @@ -39,7 +39,8 @@ impl FixedDecimalFormatterLoader for ExternalLoaderCompiledData { locale: &DataLocale, options: FixedDecimalFormatterOptions, ) -> Result { - FixedDecimalFormatter::try_new(locale, options) + let temp_loc = locale.clone().into_locale(); + FixedDecimalFormatter::try_new(temp_loc.into(), options) } } @@ -64,7 +65,8 @@ where locale: &DataLocale, options: FixedDecimalFormatterOptions, ) -> Result { - FixedDecimalFormatter::try_new_with_any_provider(self.0, locale, options) + let temp_loc = locale.clone().into_locale(); + FixedDecimalFormatter::try_new_with_any_provider(self.0, temp_loc.into(), options) } } @@ -93,7 +95,8 @@ where locale: &DataLocale, options: FixedDecimalFormatterOptions, ) -> Result { - FixedDecimalFormatter::try_new_with_buffer_provider(self.0, locale, options) + let temp_loc = locale.clone().into_locale(); + FixedDecimalFormatter::try_new_with_buffer_provider(self.0, temp_loc.into(), options) } } @@ -121,7 +124,8 @@ where locale: &DataLocale, options: FixedDecimalFormatterOptions, ) -> Result { - FixedDecimalFormatter::try_new_unstable(self.0, locale, options) + let temp_loc = locale.clone().into_locale(); + FixedDecimalFormatter::try_new_unstable(self.0, temp_loc.into(), options) } } diff --git a/components/datetime/src/format/datetime.rs b/components/datetime/src/format/datetime.rs index d8272f18f7b..0e1d8b181a2 100644 --- a/components/datetime/src/format/datetime.rs +++ b/components/datetime/src/format/datetime.rs @@ -507,7 +507,7 @@ mod tests { let mut fixed_decimal_format_options = FixedDecimalFormatterOptions::default(); fixed_decimal_format_options.grouping_strategy = GroupingStrategy::Never; let fixed_decimal_format = FixedDecimalFormatter::try_new( - &icu_locale_core::locale!("en").into(), + icu_locale_core::locale!("en").into(), fixed_decimal_format_options, ) .unwrap(); diff --git a/components/decimal/README.md b/components/decimal/README.md index f7efd78ee6a..65489a067fc 100644 --- a/components/decimal/README.md +++ b/components/decimal/README.md @@ -21,7 +21,7 @@ use icu::locale::locale; use writeable::assert_writeable_eq; let fdf = FixedDecimalFormatter::try_new( - &locale!("bn").into(), + locale!("bn").into(), Default::default(), ) .expect("locale should be present"); @@ -40,7 +40,7 @@ use icu::locale::Locale; use writeable::assert_writeable_eq; let fdf = - FixedDecimalFormatter::try_new(&Default::default(), Default::default()) + FixedDecimalFormatter::try_new(Default::default(), Default::default()) .expect("locale should be present"); let fixed_decimal = FixedDecimal::from(200050).multiplied_pow10(-2); @@ -60,7 +60,7 @@ use icu::locale::locale; use writeable::assert_writeable_eq; let fdf = FixedDecimalFormatter::try_new( - &locale!("th-u-nu-thai").into(), + locale!("th-u-nu-thai").into(), Default::default(), ) .expect("locale should be present"); diff --git a/components/decimal/benches/fixed_decimal_format.rs b/components/decimal/benches/fixed_decimal_format.rs index fd32e9a9c0f..1702426da09 100644 --- a/components/decimal/benches/fixed_decimal_format.rs +++ b/components/decimal/benches/fixed_decimal_format.rs @@ -42,7 +42,7 @@ fn overview_bench(c: &mut Criterion) { // ranging from -1e9 to 1e9. let fdf = FixedDecimalFormatter::try_new_unstable( &provider, - &Default::default(), + Default::default(), Default::default(), ) .unwrap(); diff --git a/components/decimal/examples/code_line_diff.rs b/components/decimal/examples/code_line_diff.rs index 96255b57bd9..254d2e93132 100644 --- a/components/decimal/examples/code_line_diff.rs +++ b/components/decimal/examples/code_line_diff.rs @@ -21,7 +21,7 @@ const LINES_REMOVED_ADDED: [(i64, i64); 5] = [ ]; fn main() { - let fdf = FixedDecimalFormatter::try_new(&locale!("bn").into(), Default::default()) + let fdf = FixedDecimalFormatter::try_new(locale!("bn").into(), Default::default()) .expect("locale should be present"); for (removed, added) in LINES_REMOVED_ADDED { diff --git a/components/decimal/src/format.rs b/components/decimal/src/format.rs index dca8c2a4aee..8bada17634f 100644 --- a/components/decimal/src/format.rs +++ b/components/decimal/src/format.rs @@ -76,7 +76,7 @@ mod tests { #[test] pub fn test_es_mx() { let locale = locale!("es-MX").into(); - let fmt = FixedDecimalFormatter::try_new(&locale, Default::default()).unwrap(); + let fmt = FixedDecimalFormatter::try_new(locale, Default::default()).unwrap(); let fd = "12345.67".parse().unwrap(); assert_writeable_eq!(fmt.format(&fd), "12,345.67"); } diff --git a/components/decimal/src/grouper.rs b/components/decimal/src/grouper.rs index c7e7d3369d7..14bc58e8a34 100644 --- a/components/decimal/src/grouper.rs +++ b/components/decimal/src/grouper.rs @@ -166,7 +166,7 @@ fn test_grouper() { }; let fdf = FixedDecimalFormatter::try_new_unstable( &provider.as_downcasting(), - &Default::default(), + Default::default(), options, ) .unwrap(); diff --git a/components/decimal/src/lib.rs b/components/decimal/src/lib.rs index b6e546292be..8b2ce6c0913 100644 --- a/components/decimal/src/lib.rs +++ b/components/decimal/src/lib.rs @@ -21,7 +21,7 @@ //! use writeable::assert_writeable_eq; //! //! let fdf = FixedDecimalFormatter::try_new( -//! &locale!("bn").into(), +//! locale!("bn").into(), //! Default::default(), //! ) //! .expect("locale should be present"); @@ -40,7 +40,7 @@ //! use writeable::assert_writeable_eq; //! //! let fdf = -//! FixedDecimalFormatter::try_new(&Default::default(), Default::default()) +//! FixedDecimalFormatter::try_new(Default::default(), Default::default()) //! .expect("locale should be present"); //! //! let fixed_decimal = FixedDecimal::from(200050).multiplied_pow10(-2); @@ -60,7 +60,7 @@ //! use writeable::assert_writeable_eq; //! //! let fdf = FixedDecimalFormatter::try_new( -//! &locale!("th-u-nu-thai").into(), +//! locale!("th-u-nu-thai").into(), //! Default::default(), //! ) //! .expect("locale should be present"); @@ -100,12 +100,24 @@ pub use format::FormattedFixedDecimal; use alloc::string::String; use fixed_decimal::FixedDecimal; +use icu_locale_core::preferences::{ + define_preferences, extensions::unicode::keywords::NumberingSystem, +}; use icu_provider::prelude::*; use size_test_macro::size_test; use writeable::Writeable; size_test!(FixedDecimalFormatter, fixed_decimal_formatter_size, 88); +define_preferences!( + /// The preferences for fixed decimal formatting. + FixedDecimalFormatterPreferences, + { + /// Numbering System. Corresponds to the `-u-nu` in Unicode Locale Identifier. + numbering_system: NumberingSystem + } +); + /// A formatter for [`FixedDecimal`], rendering decimal digits in an i18n-friendly way. /// /// [`FixedDecimalFormatter`] supports: @@ -133,23 +145,29 @@ impl AsRef for FixedDecimalFormatter { impl FixedDecimalFormatter { icu_provider::gen_any_buffer_data_constructors!( - (locale, options: options::FixedDecimalFormatterOptions) -> error: DataError, + (prefs: FixedDecimalFormatterPreferences, options: options::FixedDecimalFormatterOptions) -> error: DataError, /// Creates a new [`FixedDecimalFormatter`] from compiled data and an options bag. ); #[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::try_new)] pub fn try_new_unstable + ?Sized>( provider: &D, - locale: &DataLocale, + prefs: FixedDecimalFormatterPreferences, options: options::FixedDecimalFormatterOptions, ) -> Result { + let locale = DataLocale::from_preferences_locale::( + prefs.locale_prefs, + ); + let nu: &str = prefs + .numbering_system + .as_ref() + .map(|s| s.as_str()) + .unwrap_or(""); let symbols = provider .load(DataRequest { id: DataIdentifierBorrowed::for_marker_attributes_and_locale( - DataMarkerAttributes::from_str_or_panic( - locale.get_single_unicode_ext("nu").unwrap_or_default(), - ), - locale, + DataMarkerAttributes::from_str_or_panic(nu), + &locale, ), ..Default::default() })? diff --git a/components/decimal/src/options.rs b/components/decimal/src/options.rs index fb79141b65f..48a2c84d72b 100644 --- a/components/decimal/src/options.rs +++ b/components/decimal/src/options.rs @@ -32,7 +32,7 @@ impl From for FixedDecimalFormatterOptions { /// let locale = Default::default(); /// let mut options: options::FixedDecimalFormatterOptions = Default::default(); /// options.grouping_strategy = options::GroupingStrategy::Min2; -/// let fdf = FixedDecimalFormatter::try_new(&locale, options) +/// let fdf = FixedDecimalFormatter::try_new(locale, options) /// .expect("locale should be present"); /// /// let one_thousand = 1000.into(); diff --git a/components/experimental/src/compactdecimal/format.rs b/components/experimental/src/compactdecimal/format.rs index cb18e8b987b..272788d8bdc 100644 --- a/components/experimental/src/compactdecimal/format.rs +++ b/components/experimental/src/compactdecimal/format.rs @@ -31,7 +31,7 @@ impl FormattedCompactDecimal<'_> { /// use writeable::assert_writeable_eq; /// /// let short_english = CompactDecimalFormatter::try_new_short( - /// &locale!("en").into(), + /// locale!("en").into(), /// Default::default(), /// ) /// .unwrap(); diff --git a/components/experimental/src/compactdecimal/formatter.rs b/components/experimental/src/compactdecimal/formatter.rs index d14806fad7b..a82b9694a5a 100644 --- a/components/experimental/src/compactdecimal/formatter.rs +++ b/components/experimental/src/compactdecimal/formatter.rs @@ -14,12 +14,30 @@ use crate::compactdecimal::{ use alloc::borrow::Cow; use core::convert::TryFrom; use fixed_decimal::{CompactDecimal, FixedDecimal}; -use icu_decimal::FixedDecimalFormatter; -use icu_plurals::PluralRules; +use icu_decimal::{FixedDecimalFormatter, FixedDecimalFormatterPreferences}; +use icu_locale_core::preferences::{ + define_preferences, extensions::unicode::keywords::NumberingSystem, prefs_convert, +}; +use icu_plurals::{PluralRules, PluralRulesPreferences}; use icu_provider::DataError; use icu_provider::{marker::ErasedMarker, prelude::*}; use zerovec::maps::ZeroMap2dCursor; +define_preferences!( + /// The preferences for compact decimal formatting. + CompactDecimalFormatterPreferences, + { + numbering_system: NumberingSystem + } +); + +prefs_convert!( + CompactDecimalFormatterPreferences, + FixedDecimalFormatterPreferences, + { numbering_system } +); +prefs_convert!(CompactDecimalFormatterPreferences, PluralRulesPreferences); + /// A formatter that renders locale-sensitive compact numbers. /// /// # Examples @@ -30,14 +48,14 @@ use zerovec::maps::ZeroMap2dCursor; /// use writeable::assert_writeable_eq; /// /// let short_french = CompactDecimalFormatter::try_new_short( -/// &locale!("fr").into(), +/// locale!("fr").into(), /// Default::default(), /// ).unwrap(); /// /// let [long_french, long_japanese, long_bangla] = [locale!("fr"), locale!("ja"), locale!("bn")] /// .map(|locale| { /// CompactDecimalFormatter::try_new_long( -/// &locale.into(), +/// locale.into(), /// Default::default(), /// ) /// .unwrap() @@ -78,26 +96,28 @@ impl CompactDecimalFormatter { /// use icu::locale::locale; /// /// CompactDecimalFormatter::try_new_short( - /// &locale!("sv").into(), + /// locale!("sv").into(), /// Default::default(), /// ); /// ``` #[cfg(feature = "compiled_data")] pub fn try_new_short( - locale: &DataLocale, + prefs: CompactDecimalFormatterPreferences, options: CompactDecimalFormatterOptions, ) -> Result { - let temp_loc = locale.clone().into_locale(); + let locale = DataLocale::from_preferences_locale::( + prefs.locale_prefs, + ); Ok(Self { fixed_decimal_formatter: FixedDecimalFormatter::try_new( - locale, + (&prefs).into(), options.fixed_decimal_formatter_options, )?, - plural_rules: PluralRules::try_new_cardinal(temp_loc.into())?, + plural_rules: PluralRules::try_new_cardinal((&prefs).into())?, compact_data: DataProvider::::load( &crate::provider::Baked, DataRequest { - id: DataIdentifierBorrowed::for_locale(locale), + id: DataIdentifierBorrowed::for_locale(&locale), ..Default::default() }, )? @@ -107,7 +127,7 @@ impl CompactDecimalFormatter { } icu_provider::gen_any_buffer_data_constructors!( - (locale, options: CompactDecimalFormatterOptions) -> error: DataError, + (prefs: CompactDecimalFormatterPreferences, options: CompactDecimalFormatterOptions) -> error: DataError, functions: [ try_new_short: skip, try_new_short_with_any_provider, @@ -120,7 +140,7 @@ impl CompactDecimalFormatter { #[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::try_new_short)] pub fn try_new_short_unstable( provider: &D, - locale: &DataLocale, + prefs: CompactDecimalFormatterPreferences, options: CompactDecimalFormatterOptions, ) -> Result where @@ -129,18 +149,20 @@ impl CompactDecimalFormatter { + DataProvider + ?Sized, { - let temp_loc = locale.clone().into_locale(); + let locale = DataLocale::from_preferences_locale::( + prefs.locale_prefs, + ); Ok(Self { fixed_decimal_formatter: FixedDecimalFormatter::try_new_unstable( provider, - locale, + (&prefs).into(), options.fixed_decimal_formatter_options, )?, - plural_rules: PluralRules::try_new_cardinal_unstable(provider, temp_loc.into())?, + plural_rules: PluralRules::try_new_cardinal_unstable(provider, (&prefs).into())?, compact_data: DataProvider::::load( provider, DataRequest { - id: DataIdentifierBorrowed::for_locale(locale), + id: DataIdentifierBorrowed::for_locale(&locale), ..Default::default() }, )? @@ -164,26 +186,28 @@ impl CompactDecimalFormatter { /// use icu::locale::locale; /// /// CompactDecimalFormatter::try_new_long( - /// &locale!("sv").into(), + /// locale!("sv").into(), /// Default::default(), /// ); /// ``` #[cfg(feature = "compiled_data")] pub fn try_new_long( - locale: &DataLocale, + prefs: CompactDecimalFormatterPreferences, options: CompactDecimalFormatterOptions, ) -> Result { - let temp_loc = locale.clone().into_locale(); + let locale = DataLocale::from_preferences_locale::( + prefs.locale_prefs, + ); Ok(Self { fixed_decimal_formatter: FixedDecimalFormatter::try_new( - locale, + (&prefs).into(), options.fixed_decimal_formatter_options, )?, - plural_rules: PluralRules::try_new_cardinal(temp_loc.into())?, + plural_rules: PluralRules::try_new_cardinal((&prefs).into())?, compact_data: DataProvider::::load( &crate::provider::Baked, DataRequest { - id: DataIdentifierBorrowed::for_locale(locale), + id: DataIdentifierBorrowed::for_locale(&locale), ..Default::default() }, )? @@ -193,7 +217,7 @@ impl CompactDecimalFormatter { } icu_provider::gen_any_buffer_data_constructors!( - (locale, options: CompactDecimalFormatterOptions) -> error: DataError, + (prefs: CompactDecimalFormatterPreferences, options: CompactDecimalFormatterOptions) -> error: DataError, functions: [ try_new_long: skip, try_new_long_with_any_provider, @@ -206,7 +230,7 @@ impl CompactDecimalFormatter { #[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::try_new_long)] pub fn try_new_long_unstable( provider: &D, - locale: &DataLocale, + prefs: CompactDecimalFormatterPreferences, options: CompactDecimalFormatterOptions, ) -> Result where @@ -215,18 +239,20 @@ impl CompactDecimalFormatter { + DataProvider + ?Sized, { - let temp_loc = locale.clone().into_locale(); + let locale = DataLocale::from_preferences_locale::( + prefs.locale_prefs, + ); Ok(Self { fixed_decimal_formatter: FixedDecimalFormatter::try_new_unstable( provider, - locale, + (&prefs).into(), options.fixed_decimal_formatter_options, )?, - plural_rules: PluralRules::try_new_cardinal_unstable(provider, temp_loc.into())?, + plural_rules: PluralRules::try_new_cardinal_unstable(provider, (&prefs).into())?, compact_data: DataProvider::::load( provider, DataRequest { - id: DataIdentifierBorrowed::for_locale(locale), + id: DataIdentifierBorrowed::for_locale(&locale), ..Default::default() }, )? @@ -250,7 +276,7 @@ impl CompactDecimalFormatter { /// use writeable::assert_writeable_eq; /// /// let short_english = CompactDecimalFormatter::try_new_short( - /// &locale!("en").into(), + /// locale!("en").into(), /// Default::default(), /// ) /// .unwrap(); @@ -273,7 +299,7 @@ impl CompactDecimalFormatter { /// # use writeable::assert_writeable_eq; /// # /// # let short_english = CompactDecimalFormatter::try_new_short( - /// # &locale!("en").into(), + /// # locale!("en").into(), /// # Default::default(), /// # ).unwrap(); /// assert_writeable_eq!(short_english.format_i64(999_499), "999K"); @@ -305,7 +331,7 @@ impl CompactDecimalFormatter { /// use writeable::assert_writeable_eq; /// /// let short_english = CompactDecimalFormatter::try_new_short( - /// &locale!("en").into(), + /// locale!("en").into(), /// Default::default(), /// ) /// .unwrap(); @@ -328,7 +354,7 @@ impl CompactDecimalFormatter { /// # use writeable::assert_writeable_eq; /// # /// # let short_english = CompactDecimalFormatter::try_new_short( - /// # &locale!("en").into(), + /// # locale!("en").into(), /// # Default::default(), /// # ).unwrap(); /// assert_writeable_eq!(short_english.format_f64(999_499.99).unwrap(), "999K"); @@ -370,7 +396,7 @@ impl CompactDecimalFormatter { /// use writeable::assert_writeable_eq; /// /// let short_english = CompactDecimalFormatter::try_new_short( - /// &locale!("en").into(), + /// locale!("en").into(), /// Default::default(), /// ) /// .unwrap(); @@ -423,7 +449,7 @@ impl CompactDecimalFormatter { /// # use writeable::assert_writeable_eq; /// # /// # let short_english = CompactDecimalFormatter::try_new_short( - /// # &locale!("en").into(), + /// # locale!("en").into(), /// # Default::default(), /// # ).unwrap(); /// assert_writeable_eq!( @@ -519,15 +545,15 @@ impl CompactDecimalFormatter { /// use fixed_decimal::CompactDecimal; /// /// # let short_french = CompactDecimalFormatter::try_new_short( - /// # &locale!("fr").into(), + /// # locale!("fr").into(), /// # Default::default(), /// # ).unwrap(); /// # let long_french = CompactDecimalFormatter::try_new_long( - /// # &locale!("fr").into(), + /// # locale!("fr").into(), /// # Default::default() /// # ).unwrap(); /// # let long_bangla = CompactDecimalFormatter::try_new_long( - /// # &locale!("bn").into(), + /// # locale!("bn").into(), /// # Default::default() /// # ).unwrap(); /// # @@ -626,7 +652,7 @@ impl CompactDecimalFormatter { /// locale!("bn").into(), /// ] /// .map(|locale| { - /// CompactDecimalFormatter::try_new_long(&locale, Default::default()) + /// CompactDecimalFormatter::try_new_long(locale, Default::default()) /// .unwrap() /// }); /// /// French uses millions. @@ -722,9 +748,9 @@ mod tests { ]; for case in cases { let formatter = if case.short { - CompactDecimalFormatter::try_new_short(&locale!("en").into(), case.options.clone()) + CompactDecimalFormatter::try_new_short(locale!("en").into(), case.options.clone()) } else { - CompactDecimalFormatter::try_new_long(&locale!("en").into(), case.options.clone()) + CompactDecimalFormatter::try_new_long(locale!("en").into(), case.options.clone()) } .unwrap(); let result1T = formatter.format_i64(1_000_000_000_000_000); diff --git a/components/experimental/src/dimension/currency/format.rs b/components/experimental/src/dimension/currency/format.rs index 7a632ae3e36..dd9b8802998 100644 --- a/components/experimental/src/dimension/currency/format.rs +++ b/components/experimental/src/dimension/currency/format.rs @@ -84,7 +84,7 @@ mod tests { pub fn test_en_us() { let locale = locale!("en-US").into(); let currency_code = CurrencyCode(tinystr!(3, "USD")); - let fmt = CurrencyFormatter::try_new(&locale, Default::default()).unwrap(); + let fmt = CurrencyFormatter::try_new(locale, Default::default()).unwrap(); // Positive case let positive_value = "12345.67".parse().unwrap(); @@ -101,7 +101,7 @@ mod tests { pub fn test_fr_fr() { let locale = locale!("fr-FR").into(); let currency_code = CurrencyCode(tinystr!(3, "EUR")); - let fmt = CurrencyFormatter::try_new(&locale, Default::default()).unwrap(); + let fmt = CurrencyFormatter::try_new(locale, Default::default()).unwrap(); // Positive case let positive_value = "12345.67".parse().unwrap(); @@ -118,7 +118,7 @@ mod tests { pub fn test_ar_eg() { let locale = locale!("ar-EG").into(); let currency_code = CurrencyCode(tinystr!(3, "EGP")); - let fmt = CurrencyFormatter::try_new(&locale, Default::default()).unwrap(); + let fmt = CurrencyFormatter::try_new(locale, Default::default()).unwrap(); // Positive case let positive_value = "12345.67".parse().unwrap(); diff --git a/components/experimental/src/dimension/currency/formatter.rs b/components/experimental/src/dimension/currency/formatter.rs index 797d31587a2..278bdd9abfb 100644 --- a/components/experimental/src/dimension/currency/formatter.rs +++ b/components/experimental/src/dimension/currency/formatter.rs @@ -5,7 +5,13 @@ //! Experimental. use fixed_decimal::FixedDecimal; -use icu_decimal::{options::FixedDecimalFormatterOptions, FixedDecimalFormatter}; +use icu_decimal::{ + options::FixedDecimalFormatterOptions, FixedDecimalFormatter, FixedDecimalFormatterPreferences, +}; +use icu_locale_core::preferences::{ + define_preferences, extensions::unicode::keywords::NumberingSystem, prefs_convert, +}; +use icu_plurals::PluralRulesPreferences; use icu_provider::prelude::*; use super::super::provider::currency::CurrencyEssentialsV1Marker; @@ -15,6 +21,21 @@ use super::CurrencyCode; extern crate alloc; +define_preferences!( + /// The preferences for currency formatting. + CurrencyFormatterPreferences, + { + numbering_system: NumberingSystem + } +); + +prefs_convert!( + CurrencyFormatterPreferences, + FixedDecimalFormatterPreferences, + { numbering_system } +); +prefs_convert!(CurrencyFormatterPreferences, PluralRulesPreferences); + /// A formatter for monetary values. /// /// [`CurrencyFormatter`] supports: @@ -36,7 +57,7 @@ pub struct CurrencyFormatter { impl CurrencyFormatter { icu_provider::gen_any_buffer_data_constructors!( - (locale, options: super::options::CurrencyFormatterOptions) -> error: DataError, + (prefs: CurrencyFormatterPreferences, options: super::options::CurrencyFormatterOptions) -> error: DataError, functions: [ try_new: skip, try_new_with_any_provider, @@ -53,14 +74,18 @@ impl CurrencyFormatter { /// [📚 Help choosing a constructor](icu_provider::constructors) #[cfg(feature = "compiled_data")] pub fn try_new( - locale: &DataLocale, + prefs: CurrencyFormatterPreferences, options: super::options::CurrencyFormatterOptions, ) -> Result { - let fixed_decimal_formatter = - FixedDecimalFormatter::try_new(locale, FixedDecimalFormatterOptions::default())?; + let locale = + DataLocale::from_preferences_locale::(prefs.locale_prefs); + let fixed_decimal_formatter = FixedDecimalFormatter::try_new( + (&prefs).into(), + FixedDecimalFormatterOptions::default(), + )?; let essential = crate::provider::Baked .load(DataRequest { - id: DataIdentifierBorrowed::for_locale(locale), + id: DataIdentifierBorrowed::for_locale(&locale), ..Default::default() })? .payload; @@ -75,7 +100,7 @@ impl CurrencyFormatter { #[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::try_new)] pub fn try_new_unstable( provider: &D, - locale: &DataLocale, + prefs: CurrencyFormatterPreferences, options: super::options::CurrencyFormatterOptions, ) -> Result where @@ -83,14 +108,16 @@ impl CurrencyFormatter { + DataProvider + DataProvider, { + let locale = + DataLocale::from_preferences_locale::(prefs.locale_prefs); let fixed_decimal_formatter = FixedDecimalFormatter::try_new_unstable( provider, - locale, + (&prefs).into(), FixedDecimalFormatterOptions::default(), )?; let essential = provider .load(DataRequest { - id: DataIdentifierBorrowed::for_locale(locale), + id: DataIdentifierBorrowed::for_locale(&locale), ..Default::default() })? .payload; @@ -113,7 +140,7 @@ impl CurrencyFormatter { /// use writeable::Writeable; /// /// let locale = locale!("en-US").into(); - /// let fmt = CurrencyFormatter::try_new(&locale, Default::default()).unwrap(); + /// let fmt = CurrencyFormatter::try_new(locale, Default::default()).unwrap(); /// let value = "12345.67".parse().unwrap(); /// let currency_code = CurrencyCode(tinystr!(3, "USD")); /// let formatted_currency = fmt.format_fixed_decimal(&value, currency_code); diff --git a/components/experimental/src/dimension/currency/long_format.rs b/components/experimental/src/dimension/currency/long_format.rs index 9a6afcc0da1..eb2d6926ae1 100644 --- a/components/experimental/src/dimension/currency/long_format.rs +++ b/components/experimental/src/dimension/currency/long_format.rs @@ -52,7 +52,7 @@ mod tests { pub fn test_en_us() { let locale = locale!("en-US").into(); let currency_code = CurrencyCode(tinystr!(3, "USD")); - let fmt = LongCurrencyFormatter::try_new(&locale, ¤cy_code).unwrap(); + let fmt = LongCurrencyFormatter::try_new(locale, ¤cy_code).unwrap(); // Positive case let positive_value = "12345.67".parse().unwrap(); @@ -69,7 +69,7 @@ mod tests { pub fn test_fr_fr() { let locale = locale!("fr-FR").into(); let currency_code = CurrencyCode(tinystr!(3, "EUR")); - let fmt = LongCurrencyFormatter::try_new(&locale, ¤cy_code).unwrap(); + let fmt = LongCurrencyFormatter::try_new(locale, ¤cy_code).unwrap(); // Positive case let positive_value = "12345.67".parse().unwrap(); @@ -86,7 +86,7 @@ mod tests { pub fn test_ar_eg() { let locale = locale!("ar-EG").into(); let currency_code = CurrencyCode(tinystr!(3, "EGP")); - let fmt = LongCurrencyFormatter::try_new(&locale, ¤cy_code).unwrap(); + let fmt = LongCurrencyFormatter::try_new(locale, ¤cy_code).unwrap(); // Positive case let positive_value = "12345.67".parse().unwrap(); diff --git a/components/experimental/src/dimension/currency/long_formatter.rs b/components/experimental/src/dimension/currency/long_formatter.rs index 6f92480a76f..28e2c1c4fdb 100644 --- a/components/experimental/src/dimension/currency/long_formatter.rs +++ b/components/experimental/src/dimension/currency/long_formatter.rs @@ -14,7 +14,9 @@ use crate::dimension::provider::{ extended_currency::CurrencyExtendedDataV1Marker, }; -use super::{long_format::LongFormattedCurrency, CurrencyCode}; +use super::{ + formatter::CurrencyFormatterPreferences, long_format::LongFormattedCurrency, CurrencyCode, +}; extern crate alloc; @@ -41,7 +43,7 @@ pub struct LongCurrencyFormatter { impl LongCurrencyFormatter { icu_provider::gen_any_buffer_data_constructors!( - (locale: &DataLocale, currency_code: &CurrencyCode) -> error: DataError, + (prefs: CurrencyFormatterPreferences, currency_code: &CurrencyCode) -> error: DataError, functions: [ try_new: skip, try_new_with_any_provider, @@ -57,9 +59,16 @@ impl LongCurrencyFormatter { /// /// [📚 Help choosing a constructor](icu_provider::constructors) #[cfg(feature = "compiled_data")] - pub fn try_new(locale: &DataLocale, currency_code: &CurrencyCode) -> Result { - let fixed_decimal_formatter = - FixedDecimalFormatter::try_new(locale, FixedDecimalFormatterOptions::default())?; + pub fn try_new( + prefs: CurrencyFormatterPreferences, + currency_code: &CurrencyCode, + ) -> Result { + let locale = + DataLocale::from_preferences_locale::(prefs.locale_prefs); + let fixed_decimal_formatter = FixedDecimalFormatter::try_new( + (&prefs).into(), + FixedDecimalFormatterOptions::default(), + )?; let marker_attributes = DataMarkerAttributes::try_from_str(currency_code.0.as_str()) .map_err(|_| { @@ -72,7 +81,7 @@ impl LongCurrencyFormatter { .load(DataRequest { id: DataIdentifierBorrowed::for_marker_attributes_and_locale( marker_attributes, - locale, + &locale, ), ..Default::default() })? @@ -80,8 +89,7 @@ impl LongCurrencyFormatter { let patterns = crate::provider::Baked.load(Default::default())?.payload; - let temp_loc = locale.clone().into_locale(); - let plural_rules = PluralRules::try_new_cardinal(temp_loc.into())?; + let plural_rules = PluralRules::try_new_cardinal((&prefs).into())?; Ok(Self { extended, @@ -94,7 +102,7 @@ impl LongCurrencyFormatter { #[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::try_new)] pub fn try_new_unstable( provider: &D, - locale: &DataLocale, + prefs: CurrencyFormatterPreferences, currency_code: &CurrencyCode, ) -> Result where @@ -104,9 +112,11 @@ impl LongCurrencyFormatter { + DataProvider + DataProvider, { + let locale = + DataLocale::from_preferences_locale::(prefs.locale_prefs); let fixed_decimal_formatter = FixedDecimalFormatter::try_new_unstable( provider, - locale, + (&prefs).into(), FixedDecimalFormatterOptions::default(), )?; @@ -120,7 +130,7 @@ impl LongCurrencyFormatter { .load(DataRequest { id: DataIdentifierBorrowed::for_marker_attributes_and_locale( marker_attributes, - locale, + &locale, ), ..Default::default() })? @@ -128,8 +138,7 @@ impl LongCurrencyFormatter { let patterns = provider.load(Default::default())?.payload; - let temp_loc = locale.clone().into_locale(); - let plural_rules = PluralRules::try_new_cardinal_unstable(provider, temp_loc.into())?; + let plural_rules = PluralRules::try_new_cardinal_unstable(provider, (&prefs).into())?; Ok(Self { extended, @@ -151,7 +160,7 @@ impl LongCurrencyFormatter { /// /// let locale = locale!("en-US").into(); /// let currency_code = CurrencyCode(tinystr!(3, "USD")); - /// let fmt = LongCurrencyFormatter::try_new(&locale, ¤cy_code).unwrap(); + /// let fmt = LongCurrencyFormatter::try_new(locale, ¤cy_code).unwrap(); /// let value = "12345.67".parse().unwrap(); /// let formatted_currency = fmt.format_fixed_decimal(&value, currency_code); /// let mut sink = String::new(); diff --git a/components/experimental/src/dimension/percent/format.rs b/components/experimental/src/dimension/percent/format.rs index 6a55e6c6b41..9cc0e914833 100644 --- a/components/experimental/src/dimension/percent/format.rs +++ b/components/experimental/src/dimension/percent/format.rs @@ -102,16 +102,16 @@ mod tests { use writeable::assert_writeable_eq; use crate::dimension::percent::{ - formatter::PercentFormatter, + formatter::{PercentFormatter, PercentFormatterPreferences}, options::{Display, PercentFormatterOptions}, }; #[test] pub fn test_en_us() { - let locale = locale!("en-US").into(); + let prefs: PercentFormatterPreferences = locale!("en-US").into(); // Positive case let positive_value = "12345.67".parse().unwrap(); - let default_fmt = PercentFormatter::try_new(&locale, Default::default()).unwrap(); + let default_fmt = PercentFormatter::try_new(prefs.clone(), Default::default()).unwrap(); let formatted_percent = default_fmt.format(&positive_value); assert_writeable_eq!(formatted_percent, "12,345.67%"); @@ -123,7 +123,7 @@ mod tests { // Approximate Case let approx_value = "12345.67".parse().unwrap(); let approx_fmt = PercentFormatter::try_new( - &locale, + prefs.clone(), PercentFormatterOptions { display: Display::Approximate, }, @@ -134,7 +134,7 @@ mod tests { // ExplicitSign Case let explicit_fmt = PercentFormatter::try_new( - &locale, + prefs.clone(), PercentFormatterOptions { display: Display::ExplicitSign, }, @@ -146,10 +146,10 @@ mod tests { #[test] pub fn test_tr() { - let locale = locale!("tr").into(); + let prefs: PercentFormatterPreferences = locale!("tr").into(); // Positive case let positive_value = "12345.67".parse().unwrap(); - let default_fmt = PercentFormatter::try_new(&locale, Default::default()).unwrap(); + let default_fmt = PercentFormatter::try_new(prefs.clone(), Default::default()).unwrap(); let formatted_percent = default_fmt.format(&positive_value); assert_writeable_eq!(formatted_percent, "%12.345,67"); @@ -161,7 +161,7 @@ mod tests { // Approximate Case let approx_value = "12345.67".parse().unwrap(); let approx_fmt = PercentFormatter::try_new( - &locale, + prefs.clone(), PercentFormatterOptions { display: Display::Approximate, }, @@ -172,7 +172,7 @@ mod tests { // ExplicitSign Case let explicit_fmt = PercentFormatter::try_new( - &locale, + prefs.clone(), PercentFormatterOptions { display: Display::ExplicitSign, }, @@ -184,10 +184,10 @@ mod tests { #[test] pub fn test_blo() { - let locale = locale!("blo").into(); + let prefs: PercentFormatterPreferences = locale!("blo").into(); // Positive case let positive_value = "12345.67".parse().unwrap(); - let default_fmt = PercentFormatter::try_new(&locale, Default::default()).unwrap(); + let default_fmt = PercentFormatter::try_new(prefs.clone(), Default::default()).unwrap(); let formatted_percent = default_fmt.format(&positive_value); assert_writeable_eq!(formatted_percent, "%\u{a0}12\u{a0}345,67"); @@ -199,7 +199,7 @@ mod tests { // Approximate Case let approx_value = "12345.67".parse().unwrap(); let approx_fmt = PercentFormatter::try_new( - &locale, + prefs.clone(), PercentFormatterOptions { display: Display::Approximate, }, @@ -210,7 +210,7 @@ mod tests { // ExplicitSign Case let explicit_fmt = PercentFormatter::try_new( - &locale, + prefs.clone(), PercentFormatterOptions { display: Display::ExplicitSign, }, diff --git a/components/experimental/src/dimension/percent/formatter.rs b/components/experimental/src/dimension/percent/formatter.rs index 1d516cb49f1..b0f652c00c9 100644 --- a/components/experimental/src/dimension/percent/formatter.rs +++ b/components/experimental/src/dimension/percent/formatter.rs @@ -6,7 +6,10 @@ use fixed_decimal::FixedDecimal; use icu_decimal::options::FixedDecimalFormatterOptions; -use icu_decimal::FixedDecimalFormatter; +use icu_decimal::{FixedDecimalFormatter, FixedDecimalFormatterPreferences}; +use icu_locale_core::preferences::{ + define_preferences, extensions::unicode::keywords::NumberingSystem, prefs_convert, +}; use icu_provider::{ DataError, DataIdentifierBorrowed, DataLocale, DataPayload, DataProvider, DataRequest, }; @@ -17,6 +20,20 @@ use super::options::PercentFormatterOptions; extern crate alloc; +define_preferences!( + /// The preferences for percent formatting. + PercentFormatterPreferences, + { + numbering_system: NumberingSystem + } +); + +prefs_convert!( + PercentFormatterPreferences, + FixedDecimalFormatterPreferences, + { numbering_system } +); + /// A formatter for percent values. /// /// [`PercentFormatter`] supports: @@ -34,7 +51,7 @@ pub struct PercentFormatter { impl PercentFormatter { icu_provider::gen_any_buffer_data_constructors!( - (locale, options: PercentFormatterOptions) -> error: DataError, + (prefs: PercentFormatterPreferences, options: PercentFormatterOptions) -> error: DataError, functions: [ try_new: skip, try_new_with_any_provider, @@ -51,14 +68,16 @@ impl PercentFormatter { /// [📚 Help choosing a constructor](icu_provider::constructors) #[cfg(feature = "compiled_data")] pub fn try_new( - locale: &DataLocale, + prefs: PercentFormatterPreferences, options: PercentFormatterOptions, ) -> Result { - let fixed_decimal_formatter = - FixedDecimalFormatter::try_new(locale, FixedDecimalFormatterOptions::default())?; + let fixed_decimal_formatter = FixedDecimalFormatter::try_new( + (&prefs).into(), + FixedDecimalFormatterOptions::default(), + )?; PercentFormatter::try_new_with_fixed_decimal_formatter( - locale, + prefs, fixed_decimal_formatter, options, ) @@ -67,7 +86,7 @@ impl PercentFormatter { #[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::try_new)] pub fn try_new_unstable( provider: &D, - locale: &DataLocale, + prefs: PercentFormatterPreferences, options: PercentFormatterOptions, ) -> Result where @@ -77,13 +96,13 @@ impl PercentFormatter { { let fixed_decimal_formatter = FixedDecimalFormatter::try_new_unstable( provider, - locale, + (&prefs).into(), FixedDecimalFormatterOptions::default(), )?; PercentFormatter::try_new_with_fixed_decimal_formatter_unstable( provider, - locale, + prefs, fixed_decimal_formatter, options, ) @@ -100,7 +119,7 @@ impl PercentFormatter { /// use writeable::Writeable; /// /// let locale = locale!("en-US").into(); - /// let fmt = PercentFormatter::try_new(&locale, Default::default()).unwrap(); + /// let fmt = PercentFormatter::try_new(locale, Default::default()).unwrap(); /// let value = "12345.67".parse().unwrap(); /// let formatted_percent = fmt.format(&value); /// let mut sink = String::new(); @@ -128,13 +147,15 @@ where /// [📚 Help choosing a constructor](icu_provider::constructors) #[cfg(feature = "compiled_data")] pub fn try_new_with_fixed_decimal_formatter( - locale: &DataLocale, + prefs: PercentFormatterPreferences, fixed_decimal_formatter: R, options: PercentFormatterOptions, ) -> Result { + let locale = + DataLocale::from_preferences_locale::(prefs.locale_prefs); let essential = crate::provider::Baked .load(DataRequest { - id: DataIdentifierBorrowed::for_locale(locale), + id: DataIdentifierBorrowed::for_locale(&locale), ..Default::default() })? .payload; @@ -149,13 +170,15 @@ where #[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::try_new)] pub fn try_new_with_fixed_decimal_formatter_unstable( provider: &(impl DataProvider + ?Sized), - locale: &DataLocale, + prefs: PercentFormatterPreferences, fixed_decimal_formatter: R, options: PercentFormatterOptions, ) -> Result { + let locale = + DataLocale::from_preferences_locale::(prefs.locale_prefs); let essential = provider .load(DataRequest { - id: DataIdentifierBorrowed::for_locale(locale), + id: DataIdentifierBorrowed::for_locale(&locale), ..Default::default() })? .payload; diff --git a/components/experimental/src/dimension/units/format.rs b/components/experimental/src/dimension/units/format.rs index 6dfe2bb9073..09c4b8de315 100644 --- a/components/experimental/src/dimension/units/format.rs +++ b/components/experimental/src/dimension/units/format.rs @@ -91,7 +91,7 @@ fn test_basic() { ]; for (locale, unit, value, options, expected) in test_cases { - let fmt = UnitsFormatter::try_new(&locale.into(), unit, options).unwrap(); + let fmt = UnitsFormatter::try_new(locale.into(), unit, options).unwrap(); let value = value.parse().unwrap(); assert_writeable_eq!(fmt.format_fixed_decimal(&value), expected); } diff --git a/components/experimental/src/dimension/units/formatter.rs b/components/experimental/src/dimension/units/formatter.rs index 05895758b09..b5daaced589 100644 --- a/components/experimental/src/dimension/units/formatter.rs +++ b/components/experimental/src/dimension/units/formatter.rs @@ -6,8 +6,11 @@ use fixed_decimal::FixedDecimal; use icu_decimal::options::FixedDecimalFormatterOptions; -use icu_decimal::FixedDecimalFormatter; -use icu_plurals::PluralRules; +use icu_decimal::{FixedDecimalFormatter, FixedDecimalFormatterPreferences}; +use icu_locale_core::preferences::{ + define_preferences, extensions::unicode::keywords::NumberingSystem, prefs_convert, +}; +use icu_plurals::{PluralRules, PluralRulesPreferences}; use icu_provider::DataPayload; use super::format::FormattedUnit; @@ -18,6 +21,20 @@ use smallvec::SmallVec; extern crate alloc; +define_preferences!( + /// The preferences for units formatting. + UnitsFormatterPreferences, + { + numbering_system: NumberingSystem + } +); +prefs_convert!( + UnitsFormatterPreferences, + FixedDecimalFormatterPreferences, + { numbering_system } +); +prefs_convert!(UnitsFormatterPreferences, PluralRulesPreferences); + /// A formatter for measurement unit values. /// /// [`UnitsFormatter`] supports: @@ -44,7 +61,7 @@ pub struct UnitsFormatter { impl UnitsFormatter { icu_provider::gen_any_buffer_data_constructors!( - (locale, unit: &str, options: super::options::UnitsFormatterOptions) -> error: DataError, + (wprefs: UnitsFormatterPreferences, unit: &str, options: super::options::UnitsFormatterOptions) -> error: DataError, functions: [ try_new: skip, try_new_with_any_provider, @@ -75,15 +92,18 @@ impl UnitsFormatter { /// [📚 Help choosing a constructor](icu_provider::constructors) #[cfg(feature = "compiled_data")] pub fn try_new( - locale: &DataLocale, + prefs: UnitsFormatterPreferences, unit: &str, options: super::options::UnitsFormatterOptions, ) -> Result { - let fixed_decimal_formatter = - FixedDecimalFormatter::try_new(locale, FixedDecimalFormatterOptions::default())?; + let locale = + DataLocale::from_preferences_locale::(prefs.locale_prefs); + let fixed_decimal_formatter = FixedDecimalFormatter::try_new( + (&prefs).into(), + FixedDecimalFormatterOptions::default(), + )?; - let temp_loc = locale.clone().into_locale(); - let plural_rules = PluralRules::try_new_cardinal(temp_loc.into())?; + let plural_rules = PluralRules::try_new_cardinal((&prefs).into())?; // TODO: Remove this allocation once we have separate markers for different widths. let attribute = Self::attribute(options.width, unit); @@ -94,7 +114,7 @@ impl UnitsFormatter { .load(DataRequest { id: DataIdentifierBorrowed::for_marker_attributes_and_locale( unit_attribute, - locale, + &locale, ), ..Default::default() })? @@ -111,7 +131,7 @@ impl UnitsFormatter { #[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::try_new)] pub fn try_new_unstable( provider: &D, - locale: &DataLocale, + prefs: UnitsFormatterPreferences, unit: &str, options: super::options::UnitsFormatterOptions, ) -> Result @@ -121,14 +141,15 @@ impl UnitsFormatter { + DataProvider + DataProvider, { + let locale = + DataLocale::from_preferences_locale::(prefs.locale_prefs); let fixed_decimal_formatter = FixedDecimalFormatter::try_new_unstable( provider, - locale, + (&prefs).into(), FixedDecimalFormatterOptions::default(), )?; - let temp_loc = locale.clone().into_locale(); - let plural_rules = PluralRules::try_new_cardinal_unstable(provider, temp_loc.into())?; + let plural_rules = PluralRules::try_new_cardinal_unstable(provider, (&prefs).into())?; // TODO: Remove this allocation once we have separate markers for different widths. let attribute = Self::attribute(options.width, unit); @@ -139,7 +160,7 @@ impl UnitsFormatter { .load(DataRequest { id: DataIdentifierBorrowed::for_marker_attributes_and_locale( unit_attribute, - locale, + &locale, ), ..Default::default() })? diff --git a/components/experimental/src/duration/format.rs b/components/experimental/src/duration/format.rs index ed328563e5f..74fbbf9a0e1 100644 --- a/components/experimental/src/duration/format.rs +++ b/components/experimental/src/duration/format.rs @@ -640,7 +640,7 @@ mod tests { }; let options = ValidatedDurationFormatterOptions::validate(options).unwrap(); - let formatter = DurationFormatter::try_new(&locale!("und").into(), options).unwrap(); + let formatter = DurationFormatter::try_new(locale!("und").into(), options).unwrap(); let formatted = formatter.format(&duration); assert_eq!(formatted.write_to_string().into_owned(), "12:01:32.13"); } @@ -668,7 +668,7 @@ mod tests { }; let options = ValidatedDurationFormatterOptions::validate(options).unwrap(); - let formatter = DurationFormatter::try_new(&locale!("en").into(), options).unwrap(); + let formatter = DurationFormatter::try_new(locale!("en").into(), options).unwrap(); let formatted = formatter.format(&duration); assert_eq!( formatted.write_to_string().into_owned(), @@ -698,7 +698,7 @@ mod tests { }; let options = ValidatedDurationFormatterOptions::validate(options).unwrap(); - let formatter = DurationFormatter::try_new(&locale!("en").into(), options).unwrap(); + let formatter = DurationFormatter::try_new(locale!("en").into(), options).unwrap(); let formatted = formatter.format(&duration); assert_writeable_parts_eq!( &formatted, @@ -741,7 +741,7 @@ mod tests { }; let options = ValidatedDurationFormatterOptions::validate(options).unwrap(); - let formatter = DurationFormatter::try_new(&locale!("en").into(), options).unwrap(); + let formatter = DurationFormatter::try_new(locale!("en").into(), options).unwrap(); assert_eq!( formatter diff --git a/components/experimental/src/duration/formatter.rs b/components/experimental/src/duration/formatter.rs index bb75da081da..994603209fc 100644 --- a/components/experimental/src/duration/formatter.rs +++ b/components/experimental/src/duration/formatter.rs @@ -3,7 +3,7 @@ // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). use crate::dimension::provider::units::UnitsDisplayNameV1Marker; -use crate::dimension::units::formatter::UnitsFormatter; +use crate::dimension::units::formatter::{UnitsFormatter, UnitsFormatterPreferences}; use crate::dimension::units::options::{UnitsFormatterOptions, Width}; use crate::duration::options::FieldStyle; @@ -14,10 +14,33 @@ use super::{provider, Duration}; pub use super::validated_options::ValidatedDurationFormatterOptions; use icu_decimal::provider::DecimalSymbolsV2Marker; -use icu_decimal::FixedDecimalFormatter; -use icu_list::{ListFormatter, ListLength}; +use icu_decimal::{FixedDecimalFormatter, FixedDecimalFormatterPreferences}; +use icu_list::{ListFormatter, ListFormatterPreferences, ListLength}; +use icu_locale_core::preferences::{ + define_preferences, extensions::unicode::keywords::NumberingSystem, prefs_convert, +}; use icu_provider::prelude::*; +define_preferences!( + /// The preferences for duration formatting. + DurationFormatterPreferences, + { + numbering_system: NumberingSystem + } +); + +impl Copy for DurationFormatterPreferences {} + +prefs_convert!(DurationFormatterPreferences, UnitsFormatterPreferences, { + numbering_system +}); +prefs_convert!( + DurationFormatterPreferences, + FixedDecimalFormatterPreferences, + { numbering_system } +); +prefs_convert!(DurationFormatterPreferences, ListFormatterPreferences); + /// A formatter for [`Duration`](crate::duration::Duration)s. /// /// [`DurationFormatter`] supports: @@ -86,14 +109,14 @@ impl DurationUnitFormatter { #[cfg(feature = "compiled_data")] fn try_new( - locale: &DataLocale, + prefs: DurationFormatterPreferences, options: ValidatedDurationFormatterOptions, ) -> Result { let get_unit_formatter = |unit: Unit, style| { let w = DurationUnitFormatter::field_style_to_unit_width(style, options.base); let options = UnitsFormatterOptions { width: w }; - UnitsFormatter::try_new(locale, unit.as_unit_formatter_name(), options) + UnitsFormatter::try_new((&prefs).into(), unit.as_unit_formatter_name(), options) }; Ok(DurationUnitFormatter { @@ -117,7 +140,7 @@ impl DurationUnitFormatter { + DataProvider, >( provider: &D, - locale: &DataLocale, + prefs: DurationFormatterPreferences, options: ValidatedDurationFormatterOptions, ) -> Result { let get_unit_formatter = |unit: Unit, style| { @@ -126,7 +149,7 @@ impl DurationUnitFormatter { UnitsFormatter::try_new_unstable( provider, - locale, + (&prefs).into(), unit.as_unit_formatter_name(), options, ) @@ -168,7 +191,7 @@ impl From for icu_list::ListFormatterOptions { impl DurationFormatter { icu_provider::gen_any_buffer_data_constructors!( - (locale, options: ValidatedDurationFormatterOptions) -> error: DataError, + (prefs: DurationFormatterPreferences, options: ValidatedDurationFormatterOptions) -> error: DataError, functions: [ try_new: skip, try_new_with_any_provider, @@ -185,23 +208,25 @@ impl DurationFormatter { /// [📚 Help choosing a constructor](icu_provider::constructors) #[cfg(feature = "compiled_data")] pub fn try_new( - locale: &DataLocale, + prefs: DurationFormatterPreferences, options: ValidatedDurationFormatterOptions, ) -> Result { + let locale = DataLocale::from_preferences_locale::( + prefs.locale_prefs, + ); let digital = crate::provider::Baked .load(DataRequest { - id: DataIdentifierBorrowed::for_locale(locale), + id: DataIdentifierBorrowed::for_locale(&locale), ..Default::default() })? .payload; - let temp_loc = locale.clone().into_locale(); Ok(Self { digital, options, - unit: DurationUnitFormatter::try_new(locale, options)?, - list: ListFormatter::try_new_unit(temp_loc.into(), options.base.into())?, - fdf: FixedDecimalFormatter::try_new(locale, Default::default())?, + unit: DurationUnitFormatter::try_new(prefs, options)?, + list: ListFormatter::try_new_unit((&prefs).into(), options.base.into())?, + fdf: FixedDecimalFormatter::try_new((&prefs).into(), Default::default())?, }) } @@ -215,27 +240,33 @@ impl DurationFormatter { + ?Sized, >( provider: &D, - locale: &DataLocale, + prefs: DurationFormatterPreferences, options: ValidatedDurationFormatterOptions, ) -> Result { + let locale = DataLocale::from_preferences_locale::( + prefs.locale_prefs, + ); let digital = provider .load(DataRequest { - id: DataIdentifierBorrowed::for_locale(locale), + id: DataIdentifierBorrowed::for_locale(&locale), ..Default::default() })? .payload; - let temp_loc = locale.clone().into_locale(); Ok(Self { digital, options, - unit: DurationUnitFormatter::try_new_unstable(provider, locale, options)?, + unit: DurationUnitFormatter::try_new_unstable(provider, prefs, options)?, list: ListFormatter::try_new_unit_unstable( provider, - temp_loc.into(), + (&prefs).into(), options.base.into(), )?, - fdf: FixedDecimalFormatter::try_new_unstable(provider, locale, Default::default())?, + fdf: FixedDecimalFormatter::try_new_unstable( + provider, + (&prefs).into(), + Default::default(), + )?, }) } diff --git a/components/experimental/src/relativetime/relativetime.rs b/components/experimental/src/relativetime/relativetime.rs index 9f5c3d05b81..1a2ca40e7c1 100644 --- a/components/experimental/src/relativetime/relativetime.rs +++ b/components/experimental/src/relativetime/relativetime.rs @@ -5,7 +5,10 @@ use fixed_decimal::{FixedDecimal, Sign}; use icu_decimal::{ options::FixedDecimalFormatterOptions, provider::DecimalSymbolsV2Marker, FixedDecimalFormatter, + FixedDecimalFormatterPreferences, }; +use icu_locale_core::preferences::{define_preferences, prefs_convert}; +use icu_plurals::PluralRulesPreferences; use icu_plurals::{provider::CardinalV1Marker, PluralRules}; use icu_provider::marker::ErasedMarker; use icu_provider::prelude::*; @@ -14,6 +17,17 @@ use crate::relativetime::format::FormattedRelativeTime; use crate::relativetime::options::RelativeTimeFormatterOptions; use crate::relativetime::provider::*; +define_preferences!( + /// The preferences for relative time formatting. + RelativeTimeFormatterPreferences, + {} +); +prefs_convert!( + RelativeTimeFormatterPreferences, + FixedDecimalFormatterPreferences +); +prefs_convert!(RelativeTimeFormatterPreferences, PluralRulesPreferences); + /// A formatter to render locale-sensitive relative time. /// /// # Example @@ -27,7 +41,7 @@ use crate::relativetime::provider::*; /// use writeable::assert_writeable_eq; /// /// let relative_time_formatter = RelativeTimeFormatter::try_new_long_second( -/// &locale!("en").into(), +/// locale!("en").into(), /// RelativeTimeFormatterOptions::default(), /// ) /// .expect("locale should be present"); @@ -54,7 +68,7 @@ use crate::relativetime::provider::*; /// use writeable::assert_writeable_eq; /// /// let relative_time_formatter = RelativeTimeFormatter::try_new_short_day( -/// &locale!("es").into(), +/// locale!("es").into(), /// RelativeTimeFormatterOptions { /// numeric: Numeric::Auto, /// }, @@ -89,7 +103,7 @@ use crate::relativetime::provider::*; /// use writeable::assert_writeable_eq; /// /// let relative_time_formatter = RelativeTimeFormatter::try_new_narrow_year( -/// &locale!("bn").into(), +/// locale!("bn").into(), /// RelativeTimeFormatterOptions::default(), /// ) /// .expect("locale should be present"); @@ -120,19 +134,19 @@ macro_rules! constructor { /// [📚 Help choosing a constructor](icu_provider::constructors) #[cfg(feature = "compiled_data")] pub fn $baked( - locale: &DataLocale, + prefs: RelativeTimeFormatterPreferences, options: RelativeTimeFormatterOptions, ) -> Result { - let temp_loc = locale.clone().into_locale(); - let plural_rules = PluralRules::try_new_cardinal(temp_loc.into())?; + let locale = DataLocale::from_preferences_locale::<$marker>(prefs.locale_prefs); + let plural_rules = PluralRules::try_new_cardinal((&prefs).into())?; // Initialize FixedDecimalFormatter with default options let fixed_decimal_format = FixedDecimalFormatter::try_new( - locale, + (&prefs).into(), FixedDecimalFormatterOptions::default(), )?; let rt: DataResponse<$marker> = crate::provider::Baked .load(DataRequest { - id: DataIdentifierBorrowed::for_locale(locale), + id: DataIdentifierBorrowed::for_locale(&locale), ..Default::default() })?; let rt = rt.payload.cast(); @@ -145,7 +159,7 @@ macro_rules! constructor { } icu_provider::gen_any_buffer_data_constructors!( - (locale, options: RelativeTimeFormatterOptions) -> error: DataError, + (prefs: RelativeTimeFormatterPreferences, options: RelativeTimeFormatterOptions) -> error: DataError, functions: [ $baked: skip, $any, @@ -159,7 +173,7 @@ macro_rules! constructor { #[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::$baked)] pub fn $unstable( provider: &D, - locale: &DataLocale, + prefs: RelativeTimeFormatterPreferences, options: RelativeTimeFormatterOptions, ) -> Result where @@ -168,17 +182,17 @@ macro_rules! constructor { + DataProvider + ?Sized, { - let temp_loc = locale.clone().into_locale(); - let plural_rules = PluralRules::try_new_cardinal_unstable(provider, temp_loc.into())?; + let locale = DataLocale::from_preferences_locale::<$marker>(prefs.locale_prefs); + let plural_rules = PluralRules::try_new_cardinal_unstable(provider, (&prefs).into())?; // Initialize FixedDecimalFormatter with default options let fixed_decimal_format = FixedDecimalFormatter::try_new_unstable( provider, - locale, + (&prefs).into(), FixedDecimalFormatterOptions::default(), )?; let rt: DataResponse<$marker> = provider .load(DataRequest { - id: DataIdentifierBorrowed::for_locale(locale), + id: DataIdentifierBorrowed::for_locale(&locale), ..Default::default() })?; let rt = rt.payload.cast(); diff --git a/components/experimental/tests/relativetime/tests.rs b/components/experimental/tests/relativetime/tests.rs index eccec7b427d..292550ee072 100644 --- a/components/experimental/tests/relativetime/tests.rs +++ b/components/experimental/tests/relativetime/tests.rs @@ -16,7 +16,7 @@ macro_rules! generate_test { #[test] fn $test_name(){ let relative_time_formatter = RelativeTimeFormatter::$constructor( - &locale!("en").into(), + locale!("en").into(), $options ) .expect("locale should be present"); @@ -29,7 +29,7 @@ macro_rules! generate_test { )+ let relative_time_formatter = RelativeTimeFormatter::$constructor( - &locale!("ar-EG").into(), + locale!("ar-EG").into(), $options ) .expect("locale should be present"); diff --git a/components/locale_core/src/preferences/extensions/unicode/keywords/numbering_system.rs b/components/locale_core/src/preferences/extensions/unicode/keywords/numbering_system.rs index 380b62d1000..73ca20abaf5 100644 --- a/components/locale_core/src/preferences/extensions/unicode/keywords/numbering_system.rs +++ b/components/locale_core/src/preferences/extensions/unicode/keywords/numbering_system.rs @@ -23,3 +23,5 @@ struct_keyword!( crate::extensions::unicode::Value::from_subtag(Some(input.0)) } ); + +impl Copy for NumberingSystem {} diff --git a/components/locale_core/src/preferences/extensions/unicode/keywords/regional_subdivision.rs b/components/locale_core/src/preferences/extensions/unicode/keywords/regional_subdivision.rs index 7a64c0d3dfe..ce7940ad3e7 100644 --- a/components/locale_core/src/preferences/extensions/unicode/keywords/regional_subdivision.rs +++ b/components/locale_core/src/preferences/extensions/unicode/keywords/regional_subdivision.rs @@ -2,8 +2,6 @@ // called LICENSE at the top level of the ICU4X source tree // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). -use core::ops::Deref; - use crate::preferences::extensions::unicode::errors::PreferencesParseError; use crate::preferences::extensions::unicode::struct_keyword; use crate::{ @@ -31,14 +29,6 @@ struct_keyword!( } ); -impl Deref for RegionalSubdivision { - type Target = SubdivisionId; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - #[cfg(test)] mod test { use super::*; diff --git a/components/locale_core/src/preferences/extensions/unicode/macros/struct_keyword.rs b/components/locale_core/src/preferences/extensions/unicode/macros/struct_keyword.rs index 71fe48d53ea..9d01d575089 100644 --- a/components/locale_core/src/preferences/extensions/unicode/macros/struct_keyword.rs +++ b/components/locale_core/src/preferences/extensions/unicode/macros/struct_keyword.rs @@ -72,6 +72,14 @@ macro_rules! __struct_keyword { Some(self.clone().into()) } } + + impl core::ops::Deref for $name { + type Target = $value; + + fn deref(&self) -> &Self::Target { + &self.0 + } + } }; } pub use __struct_keyword as struct_keyword; diff --git a/components/locale_core/src/preferences/mod.rs b/components/locale_core/src/preferences/mod.rs index ae388fbce80..2dbce454bb5 100644 --- a/components/locale_core/src/preferences/mod.rs +++ b/components/locale_core/src/preferences/mod.rs @@ -558,5 +558,46 @@ macro_rules! __define_preferences { } ) } + +#[macro_export] +#[doc(hidden)] +macro_rules! __prefs_convert { + ( + $name1:ident, + $name2:ident + ) => { + impl From<&$name1> for $name2 { + fn from(other: &$name1) -> Self { + let mut result = Self::default(); + result.locale_prefs = other.locale_prefs; + result + } + } + }; + ( + $name1:ident, + $name2:ident, + { + $( + $key:ident + ),* + } + ) => { + impl From<&$name1> for $name2 { + fn from(other: &$name1) -> Self { + let mut result = Self::default(); + result.locale_prefs = other.locale_prefs; + $( + result.$key = other.$key; + )* + result + } + } + }; +} + #[doc(inline)] pub use __define_preferences as define_preferences; + +#[doc(inline)] +pub use __prefs_convert as prefs_convert; diff --git a/ffi/capi/src/decimal.rs b/ffi/capi/src/decimal.rs index aa05031dd4b..74aed0e8a73 100644 --- a/ffi/capi/src/decimal.rs +++ b/ffi/capi/src/decimal.rs @@ -12,6 +12,7 @@ pub mod ffi { errors::ffi::DataError, fixed_decimal::ffi::FixedDecimal, locale_core::ffi::Locale, provider::ffi::DataProvider, }; + use icu_decimal::FixedDecimalFormatterPreferences; use writeable::Writeable; @@ -40,7 +41,7 @@ pub mod ffi { locale: &Locale, grouping_strategy: Option, ) -> Result, DataError> { - let locale = locale.to_datalocale(); + let prefs = FixedDecimalFormatterPreferences::from(&locale.0); let mut options = icu_decimal::options::FixedDecimalFormatterOptions::default(); options.grouping_strategy = grouping_strategy @@ -51,7 +52,7 @@ pub mod ffi { icu_decimal::FixedDecimalFormatter::try_new_with_any_provider, icu_decimal::FixedDecimalFormatter::try_new_with_buffer_provider, provider, - &locale, + prefs, options, )?))) } @@ -123,7 +124,7 @@ pub mod ffi { grouping_sizes, digits, }), - &Default::default(), + Default::default(), options, )?, ))) diff --git a/ffi/capi/tests/missing_apis.txt b/ffi/capi/tests/missing_apis.txt index a2f4221aa23..579e22e1448 100644 --- a/ffi/capi/tests/missing_apis.txt +++ b/ffi/capi/tests/missing_apis.txt @@ -299,6 +299,8 @@ icu::datetime::options::TimePrecision#Enum icu::datetime::options::TimePrecision::into_option#FnInEnum icu::datetime::options::YearStyle#Enum icu::datetime::options::YearStyle::into_option#FnInEnum +icu::decimal::FixedDecimalFormatterPreferences#Struct +icu::decimal::FixedDecimalFormatterPreferences::extend#FnInStruct icu::list::ListFormatterOptions#Struct icu::list::ListFormatterOptions::default#FnInStruct icu::list::ListFormatterOptions::with_length#FnInStruct diff --git a/tutorials/data_provider.md b/tutorials/data_provider.md index 98e287393bf..88e1d348377 100644 --- a/tutorials/data_provider.md +++ b/tutorials/data_provider.md @@ -235,7 +235,7 @@ let provider = CustomDecimalSymbolsProvider( let formatter = FixedDecimalFormatter::try_new_unstable( &provider, - &locale!("und").into(), + locale!("und").into(), Default::default(), ) .unwrap(); @@ -244,7 +244,7 @@ assert_eq!(formatter.format_to_string(&100007i64.into()), "100,007"); let formatter = FixedDecimalFormatter::try_new_unstable( &provider, - &locale!("und-CH").into(), + locale!("und-CH").into(), Default::default(), ) .unwrap();