Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update locale_core::preferences to stakeholder alignment #5729

Merged
merged 7 commits into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 9 additions & 6 deletions components/experimental/src/duration/formatter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ impl DurationUnitFormatter {
}
}

impl From<BaseStyle> for icu_list::ListLength {
impl From<BaseStyle> for icu_list::ListFormatterOptions {
fn from(style: BaseStyle) -> Self {
// Section 1.1.13
// 1. Let lfOpts be OrdinaryObjectCreate(null).
Expand All @@ -157,11 +157,12 @@ impl From<BaseStyle> for icu_list::ListLength {
// a. Set listStyle to "short".
// 5. Perform ! CreateDataPropertyOrThrow(lfOpts, "style", listStyle).
// 6. Let lf be ! Construct(%ListFormat%, « durationFormat.[[Locale]], lfOpts »).
match style {
let length = match style {
BaseStyle::Long => ListLength::Wide,
BaseStyle::Short | BaseStyle::Digital => ListLength::Short,
BaseStyle::Narrow => ListLength::Narrow,
}
};
Self::default().with_length(length)
}
}

Expand Down Expand Up @@ -194,11 +195,12 @@ impl DurationFormatter {
})?
.payload;

let temp_loc = locale.clone().into_locale();
Ok(Self {
digital,
options,
unit: DurationUnitFormatter::try_new(locale, options)?,
list: ListFormatter::try_new_unit_with_length(locale, options.base.into())?,
list: ListFormatter::try_new_unit(temp_loc.into(), options.base.into())?,
fdf: FixedDecimalFormatter::try_new(locale, Default::default())?,
})
}
Expand All @@ -223,13 +225,14 @@ impl DurationFormatter {
})?
.payload;

let temp_loc = locale.clone().into_locale();
Ok(Self {
digital,
options,
unit: DurationUnitFormatter::try_new_unstable(provider, locale, options)?,
list: ListFormatter::try_new_unit_with_length_unstable(
list: ListFormatter::try_new_unit_unstable(
provider,
locale,
temp_loc.into(),
options.base.into(),
)?,
fdf: FixedDecimalFormatter::try_new_unstable(provider, locale, Default::default())?,
Expand Down
21 changes: 12 additions & 9 deletions components/list/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions components/list/examples/and_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@
icu_benchmark_macros::instrument!();
use icu_benchmark_macros::println;

use icu::list::{ListFormatter, ListLength};
use icu::list::{ListFormatter, ListFormatterOptions, ListLength};
use icu::locale::locale;

fn main() {
let list_formatter =
ListFormatter::try_new_and_with_length(&locale!("es").into(), ListLength::Wide).unwrap();
let list_formatter = ListFormatter::try_new_and(
locale!("es").into(),
ListFormatterOptions::default().with_length(ListLength::Wide),
)
.unwrap();

println!(
"{}",
Expand Down
46 changes: 17 additions & 29 deletions components/list/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@
//! ## Formatting *and* lists in Spanish
//!
//! ```
//! # use icu::list::{ListFormatter, ListLength};
//! # use icu::list::{ListFormatter, ListFormatterOptions, ListLength};
//! # use icu::locale::locale;
//! # use writeable::*;
//! #
//! let list_formatter = ListFormatter::try_new_and_with_length(
//! &locale!("es").into(),
//! ListLength::Wide,
//! let list_formatter = ListFormatter::try_new_and(
//! locale!("es").into(),
//! ListFormatterOptions::default()
//! .with_length(ListLength::Wide)
//! )
//! .expect("locale should be present");
//!
Expand All @@ -37,13 +38,14 @@
//! ## Formatting *or* lists in Thai
//!
//! ```
//! # use icu::list::{ListFormatter, ListLength};
//! # use icu::list::{ListFormatter, ListFormatterOptions, ListLength};
//! # use icu::locale::locale;
//! # use writeable::*;
//! #
//! let list_formatter = ListFormatter::try_new_or_with_length(
//! &locale!("th").into(),
//! ListLength::Short,
//! let list_formatter = ListFormatter::try_new_or(
//! locale!("th").into(),
//! ListFormatterOptions::default()
//! .with_length(ListLength::Short)
//! )
//! .expect("locale should be present");
//!
Expand All @@ -54,13 +56,14 @@
//! ## Formatting unit lists in English
//!
//! ```
//! # use icu::list::{ListFormatter, ListLength};
//! # use icu::list::{ListFormatter, ListFormatterOptions, ListLength};
//! # use icu::locale::locale;
//! # use writeable::*;
//! #
//! let list_formatter = ListFormatter::try_new_unit_with_length(
//! &locale!("en").into(),
//! ListLength::Wide,
//! let list_formatter = ListFormatter::try_new_unit(
//! locale!("en").into(),
//! ListFormatterOptions::default()
//! .with_length(ListLength::Wide)
//! )
//! .expect("locale should be present");
//!
Expand Down Expand Up @@ -91,25 +94,10 @@ extern crate alloc;

mod lazy_automaton;
mod list_formatter;
mod options;
mod patterns;

pub mod provider;

pub use list_formatter::*;

/// Represents the style of a list. See the
/// [CLDR spec](https://unicode.org/reports/tr35/tr35-general.html#ListPatterns)
/// for an explanation of the different styles.
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Default)]
#[non_exhaustive]
pub enum ListLength {
/// A typical list
#[default]
Wide,
/// A shorter list
Short,
/// The shortest type of list
Narrow,
// *Important*: When adding a variant here, make sure the code in
// ListFormatterPatterns::{start, middle, end, pair} stays panic-free!
}
pub use options::*;
89 changes: 53 additions & 36 deletions components/list/src/list_formatter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,22 @@
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).

use crate::provider::*;
use crate::ListLength;
use crate::{ListFormatterOptions, ListLength};
use core::fmt::{self, Write};
use icu_locale_core::preferences::define_preferences;
use icu_provider::marker::ErasedMarker;
use icu_provider::prelude::*;
use writeable::*;

#[cfg(doc)]
extern crate writeable;

define_preferences!(
/// The preferences for list formatting.
ListFormatterPreferences,
{}
);

/// A formatter that renders sequences of items in an i18n-friendly way. See the
/// [crate-level documentation](crate) for more details.
#[derive(Debug)]
Expand All @@ -22,7 +29,7 @@ pub struct ListFormatter {
macro_rules! constructor {
($name: ident, $name_any: ident, $name_buffer: ident, $name_unstable: ident, $marker: ty, $doc: literal) => {
icu_provider::gen_any_buffer_data_constructors!(
(locale, style: ListLength) -> error: DataError,
(prefs: ListFormatterPreferences, options: ListFormatterOptions) -> error: DataError,
#[doc = concat!("Creates a new [`ListFormatter`] that produces a ", $doc, "-type list using compiled data.")]
///
/// See the [CLDR spec](https://unicode.org/reports/tr35/tr35-general.html#ListPatterns) for
Expand All @@ -43,18 +50,20 @@ macro_rules! constructor {
#[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::$name)]
pub fn $name_unstable(
provider: &(impl DataProvider<$marker> + ?Sized),
locale: &DataLocale,
length: ListLength,
prefs: ListFormatterPreferences,
options: ListFormatterOptions,
) -> Result<Self, DataError> {
let length = match options.length.unwrap_or_default() {
ListLength::Narrow => ListFormatterPatternsV2::NARROW,
ListLength::Short => ListFormatterPatternsV2::SHORT,
ListLength::Wide => ListFormatterPatternsV2::WIDE,
};
let locale = get_data_locale_from_prefs(prefs);
let data = provider
.load(DataRequest {
id: DataIdentifierBorrowed::for_marker_attributes_and_locale(
match length {
ListLength::Narrow => ListFormatterPatternsV2::NARROW,
ListLength::Short => ListFormatterPatternsV2::SHORT,
ListLength::Wide => ListFormatterPatternsV2::WIDE,
},
locale),
length,
&locale),
..Default::default()
})?
.payload
Expand All @@ -64,28 +73,39 @@ macro_rules! constructor {
};
}

fn get_data_locale_from_prefs(prefs: ListFormatterPreferences) -> DataLocale {
// TODO(#5764): This should utilize region source priority.
DataLocale::from_subtags(
prefs.locale_prefs.language,
prefs.locale_prefs.script,
prefs.locale_prefs.region,
prefs.locale_prefs.variant,
prefs.locale_prefs.subdivision,
)
}

impl ListFormatter {
constructor!(
try_new_and_with_length,
try_new_and_with_length_with_any_provider,
try_new_and_with_length_with_buffer_provider,
try_new_and_with_length_unstable,
try_new_and,
try_new_and_with_any_provider,
try_new_and_with_buffer_provider,
try_new_and_unstable,
AndListV2Marker,
"and"
);
constructor!(
try_new_or_with_length,
try_new_or_with_length_with_any_provider,
try_new_or_with_length_with_buffer_provider,
try_new_or_with_length_unstable,
try_new_or,
try_new_or_with_any_provider,
try_new_or_with_buffer_provider,
try_new_or_unstable,
OrListV2Marker,
"or"
);
constructor!(
try_new_unit_with_length,
try_new_unit_with_length_with_any_provider,
try_new_unit_with_length_with_buffer_provider,
try_new_unit_with_length_unstable,
try_new_unit,
try_new_unit_with_any_provider,
try_new_unit_with_buffer_provider,
try_new_unit_unstable,
UnitListV2Marker,
"unit"
);
Expand All @@ -102,9 +122,10 @@ impl ListFormatter {
/// use icu::list::*;
/// # use icu::locale::locale;
/// # use writeable::*;
/// let formatteur = ListFormatter::try_new_and_with_length(
/// &locale!("fr").into(),
/// ListLength::Wide,
/// let formatteur = ListFormatter::try_new_and(
/// locale!("fr").into(),
/// ListFormatterOptions::default()
/// .with_length(ListLength::Wide)
/// )
/// .unwrap();
/// let pays = ["Italie", "France", "Espagne", "Allemagne"];
Expand Down Expand Up @@ -356,8 +377,8 @@ mod tests {
macro_rules! test {
($locale:literal, $type:ident, $(($input:expr, $output:literal),)+) => {
let f = ListFormatter::$type(
&icu::locale::locale!($locale).into(),
ListLength::Wide
icu::locale::locale!($locale).into(),
Default::default(),
).unwrap();
$(
assert_writeable_eq!(f.format($input.iter()), $output);
Expand All @@ -367,14 +388,14 @@ mod tests {

#[test]
fn test_basic() {
test!("fr", try_new_or_with_length, (["A", "B"], "A ou B"),);
test!("fr", try_new_or, (["A", "B"], "A ou B"),);
}

#[test]
fn test_spanish() {
test!(
"es",
try_new_and_with_length,
try_new_and,
(["x", "Mallorca"], "x y Mallorca"),
(["x", "Ibiza"], "x e Ibiza"),
(["x", "Hidalgo"], "x e Hidalgo"),
Expand All @@ -383,7 +404,7 @@ mod tests {

test!(
"es",
try_new_or_with_length,
try_new_or,
(["x", "Ibiza"], "x o Ibiza"),
(["x", "Okinawa"], "x u Okinawa"),
(["x", "8 más"], "x u 8 más"),
Expand All @@ -400,18 +421,14 @@ mod tests {
(["x", "11.000,92"], "x u 11.000,92"),
);

test!(
"es-AR",
try_new_and_with_length,
(["x", "Ibiza"], "x e Ibiza"),
);
test!("es-AR", try_new_and, (["x", "Ibiza"], "x e Ibiza"),);
}

#[test]
fn test_hebrew() {
test!(
"he",
try_new_and_with_length,
try_new_and,
(["x", "יפו"], "x ויפו"),
(["x", "Ibiza"], "x ו‑Ibiza"),
);
Expand Down
Loading