diff --git a/components/calendar/src/week_of.rs b/components/calendar/src/week_of.rs
index ad1e39dc5dc..bdd2dd6eaa7 100644
--- a/components/calendar/src/week_of.rs
+++ b/components/calendar/src/week_of.rs
@@ -7,11 +7,19 @@ use crate::{
provider::*,
types::{DayOfMonth, DayOfYearInfo, IsoWeekday, WeekOfMonth},
};
+use icu_locale_core::preferences::define_preferences;
use icu_provider::prelude::*;
/// Minimum number of days in a month unit required for using this module
pub const MIN_UNIT_DAYS: u16 = 14;
+define_preferences!(
+ /// The preferences for the week calculator.
+ [Copy]
+ WeekPreferences,
+ {}
+);
+
/// Calculator for week-of-month and week-of-year based on locale-specific configurations.
///
/// Note that things get subtly tricky for weeks that straddle the boundary between two years: different locales
@@ -32,18 +40,19 @@ pub struct WeekCalculator {
impl WeekCalculator {
icu_provider::gen_any_buffer_data_constructors!(
- (locale) -> error: DataError,
+ (prefs: WeekPreferences) -> error: DataError,
/// Creates a new [`WeekCalculator`] from compiled data.
);
#[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::try_new)]
- pub fn try_new_unstable
(provider: &P, locale: &DataLocale) -> Result
+ pub fn try_new_unstable(provider: &P, prefs: WeekPreferences) -> Result
where
P: DataProvider + ?Sized,
{
+ let locale = DataLocale::from_preferences_locale::(prefs.locale_prefs);
provider
.load(DataRequest {
- id: DataIdentifierBorrowed::for_locale(locale),
+ id: DataIdentifierBorrowed::for_locale(&locale),
..Default::default()
})
.map(|response| WeekCalculator {
@@ -68,7 +77,7 @@ impl WeekCalculator {
/// use icu::calendar::week::WeekCalculator;
///
/// let week_calculator =
- /// WeekCalculator::try_new(&icu::locale::locale!("und-GB").into())
+ /// WeekCalculator::try_new(icu::locale::locale!("und-GB").into())
/// .expect("locale should be present");
///
/// // Wednesday the 10th is in week 2:
@@ -97,7 +106,7 @@ impl WeekCalculator {
/// use icu::calendar::Date;
///
/// let week_calculator =
- /// WeekCalculator::try_new(&icu::locale::locale!("und-GB").into())
+ /// WeekCalculator::try_new(icu::locale::locale!("und-GB").into())
/// .expect("locale should be present");
///
/// let iso_date = Date::try_new_iso(2022, 8, 26).unwrap();
@@ -668,7 +677,7 @@ fn test_weekend() {
use icu_locale_core::locale;
assert_eq!(
- WeekCalculator::try_new(&locale!("und").into())
+ WeekCalculator::try_new(locale!("und").into())
.unwrap()
.weekend()
.collect::>(),
@@ -676,7 +685,7 @@ fn test_weekend() {
);
assert_eq!(
- WeekCalculator::try_new(&locale!("und-FR").into())
+ WeekCalculator::try_new(locale!("und-FR").into())
.unwrap()
.weekend()
.collect::>(),
@@ -684,7 +693,7 @@ fn test_weekend() {
);
assert_eq!(
- WeekCalculator::try_new(&locale!("und-IQ").into())
+ WeekCalculator::try_new(locale!("und-IQ").into())
.unwrap()
.weekend()
.collect::>(),
@@ -692,7 +701,7 @@ fn test_weekend() {
);
assert_eq!(
- WeekCalculator::try_new(&locale!("und-IR").into())
+ WeekCalculator::try_new(locale!("und-IR").into())
.unwrap()
.weekend()
.collect::>(),
diff --git a/components/experimental/src/dimension/units/formatter.rs b/components/experimental/src/dimension/units/formatter.rs
index 4adcef69f51..b874dd581d0 100644
--- a/components/experimental/src/dimension/units/formatter.rs
+++ b/components/experimental/src/dimension/units/formatter.rs
@@ -62,7 +62,7 @@ pub struct UnitsFormatter {
impl UnitsFormatter {
icu_provider::gen_any_buffer_data_constructors!(
- (wprefs: UnitsFormatterPreferences, unit: &str, options: super::options::UnitsFormatterOptions) -> error: DataError,
+ (prefs: UnitsFormatterPreferences, unit: &str, options: super::options::UnitsFormatterOptions) -> error: DataError,
functions: [
try_new: skip,
try_new_with_any_provider,
diff --git a/components/experimental/src/displaynames/displaynames.rs b/components/experimental/src/displaynames/displaynames.rs
index 71885a06b45..c7567e5410c 100644
--- a/components/experimental/src/displaynames/displaynames.rs
+++ b/components/experimental/src/displaynames/displaynames.rs
@@ -8,6 +8,7 @@ use crate::displaynames::options::*;
use crate::displaynames::provider::*;
use alloc::borrow::Cow;
use alloc::string::String;
+use icu_locale_core::preferences::define_preferences;
use icu_locale_core::{
subtags::Language, subtags::Region, subtags::Script, subtags::Variant, LanguageIdentifier,
Locale,
@@ -15,6 +16,13 @@ use icu_locale_core::{
use icu_provider::prelude::*;
use potential_utf::PotentialUtf8;
+define_preferences!(
+ /// The preferences for list formatting.
+ [Copy]
+ DisplayNamesPreferences,
+ {}
+);
+
/// Lookup of the locale-specific display names by region code.
///
/// # Example
@@ -27,7 +35,7 @@ use potential_utf::PotentialUtf8;
///
/// let locale = locale!("en-001").into();
/// let options: DisplayNamesOptions = Default::default();
-/// let display_name = RegionDisplayNames::try_new(&locale, options)
+/// let display_name = RegionDisplayNames::try_new(locale, options)
/// .expect("Data should load successfully");
///
/// assert_eq!(display_name.of(region!("AE")), Some("United Arab Emirates"));
@@ -40,7 +48,7 @@ pub struct RegionDisplayNames {
impl RegionDisplayNames {
icu_provider::gen_any_buffer_data_constructors!(
- (locale, options: DisplayNamesOptions) -> error: DataError,
+ (prefs: DisplayNamesPreferences, options: DisplayNamesOptions) -> error: DataError,
/// Creates a new [`RegionDisplayNames`] from locale data and an options bag using compiled data.
functions: [
try_new,
@@ -54,12 +62,14 @@ impl RegionDisplayNames {
#[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::try_new)]
pub fn try_new_unstable + ?Sized>(
provider: &D,
- locale: &DataLocale,
+ prefs: DisplayNamesPreferences,
options: DisplayNamesOptions,
) -> Result {
+ let locale =
+ DataLocale::from_preferences_locale::(prefs.locale_prefs);
let region_data = provider
.load(DataRequest {
- id: DataIdentifierBorrowed::for_locale(locale),
+ id: DataIdentifierBorrowed::for_locale(&locale),
..Default::default()
})?
.payload;
@@ -94,7 +104,7 @@ impl RegionDisplayNames {
///
/// let locale = locale!("en-001").into();
/// let options: DisplayNamesOptions = Default::default();
-/// let display_name = ScriptDisplayNames::try_new(&locale, options)
+/// let display_name = ScriptDisplayNames::try_new(locale, options)
/// .expect("Data should load successfully");
///
/// assert_eq!(display_name.of(script!("Maya")), Some("Mayan hieroglyphs"));
@@ -107,7 +117,7 @@ pub struct ScriptDisplayNames {
impl ScriptDisplayNames {
icu_provider::gen_any_buffer_data_constructors!(
- (locale, options: DisplayNamesOptions) -> error: DataError,
+ (prefs: DisplayNamesPreferences, options: DisplayNamesOptions) -> error: DataError,
/// Creates a new [`ScriptDisplayNames`] from locale data and an options bag using compiled data.
functions: [
try_new,
@@ -121,12 +131,14 @@ impl ScriptDisplayNames {
#[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::try_new)]
pub fn try_new_unstable + ?Sized>(
provider: &D,
- locale: &DataLocale,
+ prefs: DisplayNamesPreferences,
options: DisplayNamesOptions,
) -> Result {
+ let locale =
+ DataLocale::from_preferences_locale::(prefs.locale_prefs);
let script_data = provider
.load(DataRequest {
- id: DataIdentifierBorrowed::for_locale(locale),
+ id: DataIdentifierBorrowed::for_locale(&locale),
..Default::default()
})?
.payload;
@@ -161,7 +173,7 @@ impl ScriptDisplayNames {
///
/// let locale = locale!("en-001").into();
/// let options: DisplayNamesOptions = Default::default();
-/// let display_name = VariantDisplayNames::try_new(&locale, options)
+/// let display_name = VariantDisplayNames::try_new(locale, options)
/// .expect("Data should load successfully");
///
/// assert_eq!(display_name.of(variant!("POSIX")), Some("Computer"));
@@ -175,7 +187,7 @@ pub struct VariantDisplayNames {
impl VariantDisplayNames {
icu_provider::gen_any_buffer_data_constructors!(
- (locale, options: DisplayNamesOptions) -> error: DataError,
+ (prefs: DisplayNamesPreferences, options: DisplayNamesOptions) -> error: DataError,
/// Creates a new [`VariantDisplayNames`] from locale data and an options bag using compiled data.
functions: [
try_new,
@@ -189,12 +201,14 @@ impl VariantDisplayNames {
#[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::try_new)]
pub fn try_new_unstable + ?Sized>(
provider: &D,
- locale: &DataLocale,
+ prefs: DisplayNamesPreferences,
options: DisplayNamesOptions,
) -> Result {
+ let locale =
+ DataLocale::from_preferences_locale::(prefs.locale_prefs);
let variant_data = provider
.load(DataRequest {
- id: DataIdentifierBorrowed::for_locale(locale),
+ id: DataIdentifierBorrowed::for_locale(&locale),
..Default::default()
})?
.payload;
@@ -225,7 +239,7 @@ impl VariantDisplayNames {
///
/// let locale = locale!("en-001").into();
/// let options: DisplayNamesOptions = Default::default();
-/// let display_name = LanguageDisplayNames::try_new(&locale, options)
+/// let display_name = LanguageDisplayNames::try_new(locale, options)
/// .expect("Data should load successfully");
///
/// assert_eq!(display_name.of(language!("de")), Some("German"));
@@ -238,7 +252,7 @@ pub struct LanguageDisplayNames {
impl LanguageDisplayNames {
icu_provider::gen_any_buffer_data_constructors!(
- (locale, options: DisplayNamesOptions) -> error: DataError,
+ (prefs: DisplayNamesPreferences, options: DisplayNamesOptions) -> error: DataError,
/// Creates a new [`LanguageDisplayNames`] from locale data and an options bag using compiled data.
functions: [
try_new,
@@ -252,12 +266,14 @@ impl LanguageDisplayNames {
#[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::try_new)]
pub fn try_new_unstable + ?Sized>(
provider: &D,
- locale: &DataLocale,
+ prefs: DisplayNamesPreferences,
options: DisplayNamesOptions,
) -> Result {
+ let locale =
+ DataLocale::from_preferences_locale::(prefs.locale_prefs);
let language_data = provider
.load(DataRequest {
- id: DataIdentifierBorrowed::for_locale(locale),
+ id: DataIdentifierBorrowed::for_locale(&locale),
..Default::default()
})?
.payload;
@@ -296,7 +312,7 @@ impl LanguageDisplayNames {
///
/// let locale = locale!("en-001").into();
/// let options: DisplayNamesOptions = Default::default();
-/// let display_name = LocaleDisplayNamesFormatter::try_new(&locale, options)
+/// let display_name = LocaleDisplayNamesFormatter::try_new(locale, options)
/// .expect("Data should load successfully");
///
/// assert_eq!(display_name.of(&locale!("en-GB")), "British English");
@@ -322,7 +338,7 @@ pub struct LocaleDisplayNamesFormatter {
impl LocaleDisplayNamesFormatter {
icu_provider::gen_any_buffer_data_constructors!(
- (locale, options: DisplayNamesOptions) -> error: DataError,
+ (prefs: DisplayNamesPreferences, options: DisplayNamesOptions) -> error: DataError,
/// Creates a new [`LocaleDisplayNamesFormatter`] from locale data and an options bag using compiled data.
functions: [
try_new,
@@ -336,7 +352,7 @@ impl LocaleDisplayNamesFormatter {
#[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::try_new)]
pub fn try_new_unstable(
provider: &D,
- locale: &DataLocale,
+ prefs: DisplayNamesPreferences,
options: DisplayNamesOptions,
) -> Result
where
@@ -347,8 +363,10 @@ impl LocaleDisplayNamesFormatter {
+ DataProvider
+ ?Sized,
{
+ let locale =
+ DataLocale::from_preferences_locale::(prefs.locale_prefs);
let req = DataRequest {
- id: DataIdentifierBorrowed::for_locale(locale),
+ id: DataIdentifierBorrowed::for_locale(&locale),
..Default::default()
};
@@ -503,7 +521,7 @@ fn test_language_display() {
use icu_locale_core::locale;
let dialect = LocaleDisplayNamesFormatter::try_new(
- &locale!("en").into(),
+ locale!("en").into(),
DisplayNamesOptions {
language_display: LanguageDisplay::Dialect,
..Default::default()
@@ -511,7 +529,7 @@ fn test_language_display() {
)
.unwrap();
let standard = LocaleDisplayNamesFormatter::try_new(
- &locale!("en").into(),
+ locale!("en").into(),
DisplayNamesOptions {
language_display: LanguageDisplay::Standard,
..Default::default()
diff --git a/components/experimental/src/displaynames/options.rs b/components/experimental/src/displaynames/options.rs
index 5fad55fffd9..7a533a6b512 100644
--- a/components/experimental/src/displaynames/options.rs
+++ b/components/experimental/src/displaynames/options.rs
@@ -17,7 +17,7 @@
/// let locale = locale!("en-001");
/// let mut options: DisplayNamesOptions = Default::default();
/// options.style = Some(Style::Short);
-/// let display_name = RegionDisplayNames::try_new(&locale.into(), options)
+/// let display_name = RegionDisplayNames::try_new(locale.into(), options)
/// .expect("Data should load successfully");
///
/// // Full name would be "Bosnia & Herzegovina"
diff --git a/components/experimental/tests/displaynames/tests.rs b/components/experimental/tests/displaynames/tests.rs
index 5738015d3ee..53e558db6ea 100644
--- a/components/experimental/tests/displaynames/tests.rs
+++ b/components/experimental/tests/displaynames/tests.rs
@@ -82,7 +82,7 @@ fn test_concatenate() {
let locale = locale!("en-001");
let options: DisplayNamesOptions = Default::default();
- let display_name = LocaleDisplayNamesFormatter::try_new(&locale.into(), options)
+ let display_name = LocaleDisplayNamesFormatter::try_new(locale.into(), options)
.expect("Data should load successfully");
let result = display_name.of(cas.input_1);
diff --git a/components/plurals/README.md b/components/plurals/README.md
index 71a5e996a20..534b030576b 100644
--- a/components/plurals/README.md
+++ b/components/plurals/README.md
@@ -25,10 +25,10 @@ appropriate [`PluralCategory`].
```rust
use icu::locale::locale;
-use icu::plurals::{PluralCategory, PluralRuleType, PluralRules};
+use icu::plurals::{PluralCategory, PluralRules};
let pr =
- PluralRules::try_new(locale!("en").into(), PluralRuleType::Cardinal)
+ PluralRules::try_new(locale!("en").into(), Default::default())
.expect("locale should be present");
assert_eq!(pr.category_for(5_usize), PluralCategory::Other);
diff --git a/components/plurals/benches/pluralrules.rs b/components/plurals/benches/pluralrules.rs
index 875ab963ee3..3f96fb52f74 100644
--- a/components/plurals/benches/pluralrules.rs
+++ b/components/plurals/benches/pluralrules.rs
@@ -19,7 +19,8 @@ fn pluralrules(c: &mut Criterion) {
c.bench_function("plurals/pluralrules/overview", |b| {
b.iter(|| {
for lang in &plurals_data.langs {
- let pr = PluralRules::try_new(lang.into(), PluralRuleType::Cardinal).unwrap();
+ let pr =
+ PluralRules::try_new(lang.into(), PluralRuleType::Cardinal.into()).unwrap();
for s in &numbers_data.usize {
let _ = pr.category_for(*s);
}
@@ -35,13 +36,14 @@ fn pluralrules(c: &mut Criterion) {
c.bench_function("plurals/pluralrules/construct/fs", |b| {
b.iter(|| {
for lang in &plurals_data.langs {
- PluralRules::try_new(lang.into(), PluralRuleType::Ordinal).unwrap();
- PluralRules::try_new(lang.into(), PluralRuleType::Cardinal).unwrap();
+ PluralRules::try_new(lang.into(), PluralRuleType::Ordinal.into()).unwrap();
+ PluralRules::try_new(lang.into(), PluralRuleType::Cardinal.into()).unwrap();
}
});
});
- let pr = PluralRules::try_new(locale!("ru").into(), PluralRuleType::Cardinal).unwrap();
+ let pr =
+ PluralRules::try_new(locale!("ru").into(), PluralRuleType::Cardinal.into()).unwrap();
c.bench_function("plurals/pluralrules/select/fs", |b| {
b.iter(|| {
for s in &numbers_data.usize {
diff --git a/components/plurals/src/lib.rs b/components/plurals/src/lib.rs
index b027c4e37e4..3e16b7647cc 100644
--- a/components/plurals/src/lib.rs
+++ b/components/plurals/src/lib.rs
@@ -25,10 +25,10 @@
//!
//! ```
//! use icu::locale::locale;
-//! use icu::plurals::{PluralCategory, PluralRuleType, PluralRules};
+//! use icu::plurals::{PluralCategory, PluralRules};
//!
//! let pr =
-//! PluralRules::try_new(locale!("en").into(), PluralRuleType::Cardinal)
+//! PluralRules::try_new(locale!("en").into(), Default::default())
//! .expect("locale should be present");
//!
//! assert_eq!(pr.category_for(5_usize), PluralCategory::Other);
@@ -77,6 +77,7 @@
extern crate alloc;
mod operands;
+mod options;
pub mod provider;
pub mod rules;
@@ -85,6 +86,7 @@ use icu_locale_core::preferences::define_preferences;
use icu_provider::marker::ErasedMarker;
use icu_provider::prelude::*;
pub use operands::PluralOperands;
+pub use options::*;
use provider::CardinalV1Marker;
use provider::OrdinalV1Marker;
use provider::PluralRulesV1;
@@ -95,37 +97,6 @@ use provider::PluralRangesV1Marker;
#[cfg(feature = "experimental")]
use provider::UnvalidatedPluralRange;
-/// A type of a plural rule which can be associated with the [`PluralRules`] struct.
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
-#[non_exhaustive]
-pub enum PluralRuleType {
- /// Cardinal plural forms express quantities of units such as time, currency or distance,
- /// used in conjunction with a number expressed in decimal digits (i.e. "2", not "two").
- ///
- /// For example, English has two forms for cardinals:
- ///
- /// * [`One`]: `1 day`
- /// * [`Other`]: `0 days`, `2 days`, `10 days`, `0.3 days`
- ///
- /// [`One`]: PluralCategory::One
- /// [`Other`]: PluralCategory::Other
- Cardinal,
- /// Ordinal plural forms denote the order of items in a set and are always integers.
- ///
- /// For example, English has four forms for ordinals:
- ///
- /// * [`One`]: `1st floor`, `21st floor`, `101st floor`
- /// * [`Two`]: `2nd floor`, `22nd floor`, `102nd floor`
- /// * [`Few`]: `3rd floor`, `23rd floor`, `103rd floor`
- /// * [`Other`]: `4th floor`, `11th floor`, `96th floor`
- ///
- /// [`One`]: PluralCategory::One
- /// [`Two`]: PluralCategory::Two
- /// [`Few`]: PluralCategory::Few
- /// [`Other`]: PluralCategory::Other
- Ordinal,
-}
-
/// The plural categories are used to format messages with numeric placeholders, expressed as decimal numbers.
///
/// The fundamental rule for determining plural categories is the existence of minimal pairs: whenever two different
@@ -137,10 +108,10 @@ pub enum PluralRuleType {
///
/// ```
/// use icu::locale::locale;
-/// use icu::plurals::{PluralCategory, PluralRuleType, PluralRules};
+/// use icu::plurals::{PluralCategory, PluralRules};
///
/// let pr =
-/// PluralRules::try_new(locale!("en").into(), PluralRuleType::Cardinal)
+/// PluralRules::try_new(locale!("en").into(), Default::default())
/// .expect("locale should be present");
///
/// assert_eq!(pr.category_for(5_usize), PluralCategory::Other);
@@ -276,10 +247,10 @@ define_preferences!(
///
/// ```
/// use icu::locale::locale;
-/// use icu::plurals::{PluralCategory, PluralRuleType, PluralRules};
+/// use icu::plurals::{PluralCategory, PluralRules};
///
/// let pr =
-/// PluralRules::try_new(locale!("en").into(), PluralRuleType::Cardinal)
+/// PluralRules::try_new(locale!("en").into(), Default::default())
/// .expect("locale should be present");
///
/// assert_eq!(pr.category_for(5_usize), PluralCategory::Other);
@@ -299,22 +270,21 @@ impl AsRef for PluralRules {
impl PluralRules {
icu_provider::gen_any_buffer_data_constructors!(
- (prefs: PluralRulesPreferences, rule_type: PluralRuleType) -> error: DataError,
+ (prefs: PluralRulesPreferences, options: PluralRulesOptions) -> error: DataError,
/// Constructs a new `PluralRules` for a given locale and type using compiled data.
///
/// # Examples
///
/// ```
/// use icu::locale::locale;
- /// use icu::plurals::{PluralRuleType, PluralRules};
+ /// use icu::plurals::PluralRules;
///
/// let _ = PluralRules::try_new(
/// locale!("en").into(),
- /// PluralRuleType::Cardinal,
+ /// Default::default(),
/// ).expect("locale should be present");
/// ```
///
- /// [`type`]: PluralRuleType
/// [`data provider`]: icu_provider
);
@@ -322,9 +292,9 @@ impl PluralRules {
pub fn try_new_unstable(
provider: &(impl DataProvider + DataProvider + ?Sized),
prefs: PluralRulesPreferences,
- rule_type: PluralRuleType,
+ options: PluralRulesOptions,
) -> Result {
- match rule_type {
+ match options.rule_type.unwrap_or_default() {
PluralRuleType::Cardinal => Self::try_new_cardinal_unstable(provider, prefs),
PluralRuleType::Ordinal => Self::try_new_ordinal_unstable(provider, prefs),
}
@@ -444,10 +414,10 @@ impl PluralRules {
///
/// ```
/// use icu::locale::locale;
- /// use icu::plurals::{PluralCategory, PluralRuleType, PluralRules};
+ /// use icu::plurals::{PluralCategory, PluralRules};
///
/// let pr =
- /// PluralRules::try_new(locale!("en").into(), PluralRuleType::Cardinal)
+ /// PluralRules::try_new(locale!("en").into(), Default::default())
/// .expect("locale should be present");
///
/// match pr.category_for(1_usize) {
@@ -469,10 +439,9 @@ impl PluralRules {
///
/// ```
/// use icu::locale::locale;
- /// use icu::plurals::{PluralCategory, PluralOperands};
- /// use icu::plurals::{PluralRuleType, PluralRules};
+ /// use icu::plurals::{PluralRules, PluralCategory, PluralOperands};
/// #
- /// # let pr = PluralRules::try_new(locale!("en").into(), PluralRuleType::Cardinal)
+ /// # let pr = PluralRules::try_new(locale!("en").into(), Default::default())
/// # .expect("locale should be present");
///
/// let operands = PluralOperands::try_from(-5).expect("Failed to parse to operands.");
@@ -516,10 +485,10 @@ impl PluralRules {
///
/// ```
/// use icu::locale::locale;
- /// use icu::plurals::{PluralCategory, PluralRuleType, PluralRules};
+ /// use icu::plurals::{PluralCategory, PluralRules};
///
/// let pr =
- /// PluralRules::try_new(locale!("fr").into(), PluralRuleType::Cardinal)
+ /// PluralRules::try_new(locale!("fr").into(), Default::default())
/// .expect("locale should be present");
///
/// let mut categories = pr.categories();
@@ -567,12 +536,11 @@ impl PluralRules {
///
/// ```
/// use icu::locale::locale;
-/// use icu::plurals::{PluralCategory, PluralOperands};
-/// use icu::plurals::{PluralRuleType, PluralRulesWithRanges};
+/// use icu::plurals::{PluralRulesWithRanges, PluralCategory, PluralOperands};
///
/// let ranges = PluralRulesWithRanges::try_new(
/// locale!("ar").into(),
-/// PluralRuleType::Cardinal,
+/// Default::default(),
/// )
/// .expect("locale should be present");
///
@@ -598,18 +566,18 @@ pub struct PluralRulesWithRanges {
impl PluralRulesWithRanges {
icu_provider::gen_any_buffer_data_constructors!(
- (prefs: PluralRulesPreferences, rule_type: PluralRuleType) -> error: DataError,
+ (prefs: PluralRulesPreferences, options: PluralRulesOptions) -> error: DataError,
/// Constructs a new `PluralRulesWithRanges` for a given locale using compiled data.
///
/// # Examples
///
/// ```
/// use icu::locale::locale;
- /// use icu::plurals::{PluralRuleType, PluralRulesWithRanges};
+ /// use icu::plurals::PluralRulesWithRanges;
///
/// let _ = PluralRulesWithRanges::try_new(
/// locale!("en").into(),
- /// PluralRuleType::Cardinal,
+ /// Default::default(),
/// ).expect("locale should be present");
/// ```
);
@@ -621,9 +589,9 @@ impl PluralRulesWithRanges {
+ DataProvider
+ ?Sized),
prefs: PluralRulesPreferences,
- rule_type: PluralRuleType,
+ options: PluralRulesOptions,
) -> Result {
- match rule_type {
+ match options.rule_type.unwrap_or_default() {
PluralRuleType::Cardinal => Self::try_new_cardinal_unstable(provider, prefs),
PluralRuleType::Ordinal => Self::try_new_ordinal_unstable(provider, prefs),
}
@@ -725,9 +693,9 @@ where
///
/// ```
/// use icu::locale::locale;
- /// use icu::plurals::{PluralRuleType, PluralRulesWithRanges, PluralRules};
+ /// use icu::plurals::{PluralRulesWithRanges, PluralRules};
///
- /// let rules = PluralRules::try_new(locale!("en").into(), PluralRuleType::Cardinal)
+ /// let rules = PluralRules::try_new(locale!("en").into(), Default::default())
/// .expect("locale should be present");
///
/// let _ =
@@ -791,12 +759,12 @@ where
/// ```
/// use icu::locale::locale;
/// use icu::plurals::{
- /// PluralCategory, PluralOperands, PluralRuleType, PluralRulesWithRanges,
+ /// PluralCategory, PluralOperands, PluralRulesWithRanges,
/// };
///
/// let ranges = PluralRulesWithRanges::try_new(
/// locale!("ro").into(),
- /// PluralRuleType::Cardinal,
+ /// Default::default(),
/// )
/// .expect("locale should be present");
/// let operands: PluralOperands =
@@ -833,11 +801,12 @@ where
///
/// ```
/// use icu::locale::locale;
- /// use icu::plurals::{PluralCategory, PluralRuleType, PluralRulesWithRanges};
+ /// use icu::plurals::{PluralCategory, PluralRuleType, PluralRulesOptions, PluralRulesWithRanges};
///
/// let ranges = PluralRulesWithRanges::try_new(
/// locale!("sl").into(),
- /// PluralRuleType::Ordinal,
+ /// PluralRulesOptions::default()
+ /// .with_type(PluralRuleType::Ordinal),
/// )
/// .expect("locale should be present");
///
diff --git a/components/plurals/src/options.rs b/components/plurals/src/options.rs
new file mode 100644
index 00000000000..0182d3beb5d
--- /dev/null
+++ b/components/plurals/src/options.rs
@@ -0,0 +1,80 @@
+// This file is part of ICU4X. For terms of use, please see the file
+// called LICENSE at the top level of the ICU4X source tree
+// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
+
+/// A list of options set by the developer to adjust the behavior of the PluralRules.
+///
+/// # Examples
+/// ```
+/// use icu::plurals::{PluralRulesOptions, PluralRuleType};
+///
+/// let options = PluralRulesOptions::default()
+/// .with_type(PluralRuleType::Cardinal);
+/// ```
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+#[non_exhaustive]
+pub struct PluralRulesOptions {
+ /// Plural rule type to use.
+ pub rule_type: Option,
+}
+
+impl Default for PluralRulesOptions {
+ fn default() -> Self {
+ Self::default()
+ }
+}
+
+impl PluralRulesOptions {
+ /// Constructs a new [`PluralRulesOptions`] struct.
+ pub const fn default() -> Self {
+ Self { rule_type: None }
+ }
+
+ /// Auguments the struct with the set [`PluralRuleType`].
+ pub const fn with_type(mut self, rule_type: PluralRuleType) -> Self {
+ self.rule_type = Some(rule_type);
+ self
+ }
+}
+
+impl From for PluralRulesOptions {
+ fn from(value: PluralRuleType) -> Self {
+ Self {
+ rule_type: Some(value),
+ }
+ }
+}
+
+/// A type of a plural rule which can be associated with the [`PluralRules`] struct.
+///
+/// [`PluralRules`]: crate::PluralRules
+#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Default)]
+#[non_exhaustive]
+pub enum PluralRuleType {
+ /// Cardinal plural forms express quantities of units such as time, currency or distance,
+ /// used in conjunction with a number expressed in decimal digits (i.e. "2", not "two").
+ ///
+ /// For example, English has two forms for cardinals:
+ ///
+ /// * [`One`]: `1 day`
+ /// * [`Other`]: `0 days`, `2 days`, `10 days`, `0.3 days`
+ ///
+ /// [`One`]: crate::PluralCategory::One
+ /// [`Other`]: crate::PluralCategory::Other
+ #[default]
+ Cardinal,
+ /// Ordinal plural forms denote the order of items in a set and are always integers.
+ ///
+ /// For example, English has four forms for ordinals:
+ ///
+ /// * [`One`]: `1st floor`, `21st floor`, `101st floor`
+ /// * [`Two`]: `2nd floor`, `22nd floor`, `102nd floor`
+ /// * [`Few`]: `3rd floor`, `23rd floor`, `103rd floor`
+ /// * [`Other`]: `4th floor`, `11th floor`, `96th floor`
+ ///
+ /// [`One`]: crate::PluralCategory::One
+ /// [`Two`]: crate::PluralCategory::Two
+ /// [`Few`]: crate::PluralCategory::Few
+ /// [`Other`]: crate::PluralCategory::Other
+ Ordinal,
+}
diff --git a/components/plurals/tests/fixtures/mod.rs b/components/plurals/tests/fixtures/mod.rs
index 989a676e068..556080edd22 100644
--- a/components/plurals/tests/fixtures/mod.rs
+++ b/components/plurals/tests/fixtures/mod.rs
@@ -5,7 +5,7 @@
use fixed_decimal::FixedDecimal;
#[cfg(feature = "experimental")]
use icu_plurals::PluralOperands;
-use icu_plurals::{PluralCategory, PluralRuleType};
+use icu_plurals::{PluralCategory, PluralRuleType, PluralRulesOptions};
use serde::Deserialize;
/// Defines the data-driven test sets for the operands.
@@ -133,11 +133,11 @@ pub enum PluralRuleTypeInput {
Ordinal,
}
-impl From for PluralRuleType {
+impl From for PluralRulesOptions {
fn from(other: PluralRuleTypeInput) -> Self {
match other {
- PluralRuleTypeInput::Cardinal => PluralRuleType::Cardinal,
- PluralRuleTypeInput::Ordinal => PluralRuleType::Ordinal,
+ PluralRuleTypeInput::Cardinal => PluralRuleType::Cardinal.into(),
+ PluralRuleTypeInput::Ordinal => PluralRuleType::Ordinal.into(),
}
}
}
diff --git a/components/plurals/tests/plurals.rs b/components/plurals/tests/plurals.rs
index f964626fa80..df479ea8fc4 100644
--- a/components/plurals/tests/plurals.rs
+++ b/components/plurals/tests/plurals.rs
@@ -3,13 +3,13 @@
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
use icu_locale_core::{langid, locale};
-use icu_plurals::{provider::CardinalV1Marker, PluralCategory, PluralRuleType, PluralRules};
+use icu_plurals::{provider::CardinalV1Marker, PluralCategory, PluralRules};
use icu_provider::prelude::*;
#[test]
fn test_plural_rules() {
assert_eq!(
- PluralRules::try_new(locale!("en").into(), PluralRuleType::Cardinal)
+ PluralRules::try_new(locale!("en").into(), Default::default())
.unwrap()
.category_for(5_usize),
PluralCategory::Other
diff --git a/components/plurals/tests/ranges.rs b/components/plurals/tests/ranges.rs
index 0271462b14a..156ce17b13f 100644
--- a/components/plurals/tests/ranges.rs
+++ b/components/plurals/tests/ranges.rs
@@ -3,7 +3,7 @@
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
use icu_locale_core::locale;
-use icu_plurals::{PluralCategory, PluralOperands, PluralRuleType, PluralRulesWithRanges};
+use icu_plurals::{PluralCategory, PluralOperands, PluralRulesWithRanges};
#[test]
fn test_plural_ranges_raw() {
@@ -37,8 +37,7 @@ fn test_plural_ranges_missing_data_fallback() {
#[test]
fn test_plural_ranges_full() {
- let ranges =
- PluralRulesWithRanges::try_new(locale!("sl").into(), PluralRuleType::Cardinal).unwrap();
+ let ranges = PluralRulesWithRanges::try_new(locale!("sl").into(), Default::default()).unwrap();
let start: PluralOperands = "0.5".parse().unwrap(); // PluralCategory::Other
let end: PluralOperands = PluralOperands::from(1); // PluralCategory::One
diff --git a/ffi/capi/src/displaynames.rs b/ffi/capi/src/displaynames.rs
index 3234f87b8ce..0741ec95f3a 100644
--- a/ffi/capi/src/displaynames.rs
+++ b/ffi/capi/src/displaynames.rs
@@ -70,7 +70,7 @@ pub mod ffi {
locale: &Locale,
options: DisplayNamesOptionsV1,
) -> Result, DataError> {
- let locale = locale.to_datalocale();
+ let prefs = (&locale.0).into();
let options = icu_experimental::displaynames::DisplayNamesOptions::from(options);
Ok(Box::new(LocaleDisplayNamesFormatter(
@@ -79,7 +79,7 @@ pub mod ffi {
icu_experimental::displaynames::LocaleDisplayNamesFormatter::try_new_with_any_provider,
icu_experimental::displaynames::LocaleDisplayNamesFormatter::try_new_with_buffer_provider,
provider,
- &locale,
+ prefs,
options,
)?,
)))
@@ -102,13 +102,13 @@ pub mod ffi {
provider: &DataProvider,
locale: &Locale,
) -> Result, DataError> {
- let locale = locale.to_datalocale();
+ let prefs = (&locale.0).into();
Ok(Box::new(RegionDisplayNames(call_constructor!(
icu_experimental::displaynames::RegionDisplayNames::try_new,
icu_experimental::displaynames::RegionDisplayNames::try_new_with_any_provider,
icu_experimental::displaynames::RegionDisplayNames::try_new_with_buffer_provider,
provider,
- &locale,
+ prefs,
Default::default()
)?)))
}
diff --git a/ffi/capi/src/week.rs b/ffi/capi/src/week.rs
index 4c7c2e3b023..8350330e389 100644
--- a/ffi/capi/src/week.rs
+++ b/ffi/capi/src/week.rs
@@ -40,14 +40,14 @@ pub mod ffi {
provider: &DataProvider,
locale: &Locale,
) -> Result, DataError> {
- let locale = locale.to_datalocale();
+ let prefs = (&locale.0).into();
Ok(Box::new(WeekCalculator(call_constructor!(
icu_calendar::week::WeekCalculator::try_new,
icu_calendar::week::WeekCalculator::try_new_with_any_provider,
icu_calendar::week::WeekCalculator::try_new_with_buffer_provider,
provider,
- &locale,
+ prefs,
)?)))
}
diff --git a/ffi/capi/tests/missing_apis.txt b/ffi/capi/tests/missing_apis.txt
index 5f680e137f8..f6e6f8709e5 100644
--- a/ffi/capi/tests/missing_apis.txt
+++ b/ffi/capi/tests/missing_apis.txt
@@ -489,6 +489,9 @@ icu::plurals::PluralElements::with_zero_value#FnInStruct
icu::plurals::PluralElements::zero#FnInStruct
icu::plurals::PluralOperands::is_exactly_one#FnInStruct
icu::plurals::PluralOperands::is_exactly_zero#FnInStruct
+icu::plurals::PluralRulesOptions#Struct
+icu::plurals::PluralRulesOptions::default#FnInStruct
+icu::plurals::PluralRulesOptions::with_type#FnInStruct
icu::plurals::PluralRulesPreferences#Struct
icu::plurals::PluralRulesPreferences::extend#FnInStruct
icu::properties::PropertyNamesLong#Struct
diff --git a/ffi/ecma402/src/pluralrules.rs b/ffi/ecma402/src/pluralrules.rs
index 64ca7eda5ba..baa4bc9e3ac 100644
--- a/ffi/ecma402/src/pluralrules.rs
+++ b/ffi/ecma402/src/pluralrules.rs
@@ -251,7 +251,7 @@ impl ecma402_traits::pluralrules::PluralRules for PluralRules {
let rule_type = internal::to_icu4x_type(&opts.in_type);
- let rep = ipr::PluralRules::try_new(prefs, rule_type)?;
+ let rep = ipr::PluralRules::try_new(prefs, rule_type.into())?;
Ok(Self { opts, rep })
}
diff --git a/tutorials/rust/experimental/src/main.rs b/tutorials/rust/experimental/src/main.rs
index b773da04282..40ef1026391 100644
--- a/tutorials/rust/experimental/src/main.rs
+++ b/tutorials/rust/experimental/src/main.rs
@@ -11,7 +11,7 @@ use icu::locale::{locale, subtags::region};
fn main() {
let names = RegionDisplayNames::try_new(
- &locale!("fr").into(),
+ locale!("fr").into(),
Default::default(),
)
.expect("locale 'fr' should be present in compiled data");