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

Support dateSkeleton pattern lookup in datagen #5826

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
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
20 changes: 20 additions & 0 deletions components/datetime/src/provider/pattern/reference/pattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,26 @@ impl Pattern {
pub(crate) fn to_runtime_pattern(&self) -> runtime::Pattern<'static> {
runtime::Pattern::from(self)
}

/// Replace fields with their equivalent canonical forms.
///
/// For example, replace "GGG" with "G".
#[cfg(feature = "datagen")]
pub fn canonicalize(&mut self) {
use crate::fields::{Field, FieldLength, FieldSymbol};

for item in self.items.iter_mut() {
match item {
PatternItem::Field(ref mut field @ Field {
symbol: FieldSymbol::Era,
length: FieldLength::Three
}) => {
field.length = FieldLength::One;
}
_ => {}
}
}
}
}

impl From<Vec<PatternItem>> for Pattern {
Expand Down
16 changes: 14 additions & 2 deletions components/datetime/src/provider/skeleton/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
use crate::{
fields::{self, Field, FieldLength, FieldSymbol},
options::FractionalSecondDigits,
provider::pattern::{runtime::Pattern, PatternItem},
provider::pattern::{reference, runtime::Pattern, PatternItem},
provider::skeleton::PatternPlurals,
};

Expand Down Expand Up @@ -599,11 +599,23 @@ impl From<&DateTimePattern> for Bag {

impl From<&Pattern<'_>> for Bag {
fn from(pattern: &Pattern) -> Self {
Self::from_pattern_items(pattern.items.iter())
}
}

impl From<&reference::Pattern> for Bag {
fn from(pattern: &reference::Pattern) -> Self {
Self::from_pattern_items(pattern.items.iter().copied())
}
}

impl Bag {
fn from_pattern_items(pattern_items: impl Iterator<Item = PatternItem>) -> Self {
let mut bag: Bag = Default::default();

// Transform the fields into components per:
// https://unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
for item in pattern.items.iter() {
for item in pattern_items {
let field = match item {
PatternItem::Field(ref field) => field,
PatternItem::Literal(_) => continue,
Expand Down
11 changes: 5 additions & 6 deletions components/datetime/src/provider/skeleton/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::{
};

#[cfg(feature = "datagen")]
use crate::provider::calendar::{DateLengthsV1, TimeLengthsV1};
use crate::provider::pattern::CoarseHourCycle;

// The following scalar values are for testing the suitability of a skeleton's field for the
// given input. Per UTS 35, the better the fit of a pattern, the "lower the distance". In this
Expand Down Expand Up @@ -535,21 +535,20 @@ impl components::Bag {
pub fn select_pattern<'data>(
self,
skeletons: &DateSkeletonPatternsV1<'data>,
date_patterns: &DateLengthsV1<'data>,
time_patterns: &TimeLengthsV1<'data>,
preferred_hour_cycle: CoarseHourCycle,
length_patterns: &GenericLengthPatternsV1<'data>,
) -> PatternPlurals<'data> {
use crate::provider::pattern::runtime::Pattern;
use crate::provider::pattern::CoarseHourCycle;
use icu_locale_core::preferences::extensions::unicode::keywords::HourCycle;

let default_hour_cycle = match time_patterns.preferred_hour_cycle {
let default_hour_cycle = match preferred_hour_cycle {
CoarseHourCycle::H11H12 => HourCycle::H12,
CoarseHourCycle::H23H24 => HourCycle::H23,
};
let fields = self.to_vec_fields(default_hour_cycle);
match create_best_pattern_for_fields(
skeletons,
&date_patterns.length_combinations,
length_patterns,
&fields,
&self,
false,
Expand Down
10 changes: 8 additions & 2 deletions provider/source/src/cldr_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use icu_provider::DataError;
use icu_provider_adapters::fixed::FixedProvider;
use icu_provider_adapters::fork::ForkByMarkerProvider;
use icu_provider_adapters::make_forking_provider;
use writeable::Writeable;
use std::collections::BTreeSet;
use std::collections::HashSet;
use std::fmt::Debug;
Expand Down Expand Up @@ -91,7 +92,7 @@ impl CldrCache {
levels: impl IntoIterator<Item = CoverageLevel>,
) -> Result<Vec<DataLocale>, DataError> {
let levels = levels.into_iter().collect::<HashSet<_>>();
Ok(self
let mut locales: Vec<DataLocale> = self
.serde_cache
.read_and_parse_json::<crate::cldr_serde::coverage_levels::Resource>(
"cldr-core/coverageLevels.json",
Expand All @@ -103,7 +104,12 @@ impl CldrCache {
.map(Into::into)
// `und` needs to be part of every set
.chain([Default::default()])
.collect())
.collect();
locales.sort_by(|a, b| {
let b = b.write_to_string();
a.strict_cmp(b.as_bytes())
});
Ok(locales)
}

pub(crate) fn dir_suffix(&self) -> Result<&'static str, DataError> {
Expand Down
4 changes: 4 additions & 0 deletions provider/source/src/cldr_serde/ca.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,10 @@ pub(crate) struct Dates {
pub(crate) date_formats: LengthPatterns,
#[serde(rename = "timeFormats")]
pub(crate) time_formats: LengthPatterns,
#[serde(rename = "dateSkeletons")]
pub(crate) date_skeletons: LengthPatterns,
#[serde(rename = "timeSkeletons")]
pub(crate) time_skeletons: LengthPatterns,
#[serde(rename = "dateTimeFormats")]
pub(crate) datetime_formats: DateTimeFormats,
}
Expand Down
2 changes: 1 addition & 1 deletion provider/source/src/datetime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ mod test {
.get_datetime_resources(&langid!("fil").into(), Either::Left(&value!("gregory")))
.unwrap();

let skeletons = DateSkeletonPatternsV1::from(&data).0;
let skeletons = DateSkeletonPatternsV1::from(&data.datetime_formats.available_formats).0;

assert_eq!(
Some(
Expand Down
Loading
Loading