1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-28 22:05:06 +00:00

LibUnicode: Generate per-region week data

This includes:
* The minimum number of days in a week for that week to count as the
  first week of a new year.
* The day to be shown as the first day of the week in a calendar.
* The start/end days of the weekend.

Like the existing hour cycle data, week data is presented per-region in
the CLDR, rather than per-locale. The method to add likely subtags to a
locale to perform region lookups is the same.

The list of regions in the CLDR for hour cycle, minimum days, first day,
and weekend days are quite different. So rather than changing the
existing HourCycleRegion enum to a generic Region enum, we generate
separate enums for each of the week data fields. This allows each lookup
into these fields to remain simple array-based index access, without any
"jumps" for regions that don't have CLDR data for a field.
This commit is contained in:
Timothy Flynn 2022-07-06 08:21:32 -04:00 committed by Linus Groh
parent 88a560dd84
commit 12e7c0808a
4 changed files with 192 additions and 10 deletions

View file

@ -94,27 +94,40 @@ StringView calendar_pattern_style_to_string(CalendarPatternStyle style)
Optional<HourCycleRegion> __attribute__((weak)) hour_cycle_region_from_string(StringView) { return {}; }
Vector<HourCycle> __attribute__((weak)) get_regional_hour_cycles(StringView) { return {}; }
// https://unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
Vector<Unicode::HourCycle> get_locale_hour_cycles(StringView locale)
template<typename GetRegionalValues>
static auto find_regional_values_for_locale(StringView locale, GetRegionalValues&& get_regional_values)
{
if (auto hour_cycles = get_regional_hour_cycles(locale); !hour_cycles.is_empty())
return hour_cycles;
auto has_value = [](auto const& container) {
if constexpr (requires { container.has_value(); })
return container.has_value();
else
return !container.is_empty();
};
auto return_default_hour_cycles = [&]() { return get_regional_hour_cycles("001"sv); };
if (auto regional_values = get_regional_values(locale); has_value(regional_values))
return regional_values;
auto return_default_values = [&]() { return get_regional_values("001"sv); };
auto language = parse_unicode_language_id(locale);
if (!language.has_value())
return return_default_hour_cycles();
return return_default_values();
if (!language->region.has_value())
language = add_likely_subtags(*language);
if (!language.has_value() || !language->region.has_value())
return return_default_hour_cycles();
return return_default_values();
if (auto hour_cycles = get_regional_hour_cycles(*language->region); !hour_cycles.is_empty())
return hour_cycles;
if (auto regional_values = get_regional_values(*language->region); has_value(regional_values))
return regional_values;
return return_default_hour_cycles();
return return_default_values();
}
// https://unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
Vector<Unicode::HourCycle> get_locale_hour_cycles(StringView locale)
{
return find_regional_values_for_locale(locale, get_regional_hour_cycles);
}
Optional<Unicode::HourCycle> get_default_regional_hour_cycle(StringView locale)
@ -124,6 +137,38 @@ Optional<Unicode::HourCycle> get_default_regional_hour_cycle(StringView locale)
return {};
}
Optional<MinimumDaysRegion> __attribute__((weak)) minimum_days_region_from_string(StringView) { return {}; }
Optional<u8> __attribute__((weak)) get_regional_minimum_days(StringView) { return {}; }
Optional<u8> get_locale_minimum_days(StringView locale)
{
return find_regional_values_for_locale(locale, get_regional_minimum_days);
}
Optional<FirstDayRegion> __attribute__((weak)) first_day_region_from_string(StringView) { return {}; }
Optional<Weekday> __attribute__((weak)) get_regional_first_day(StringView) { return {}; }
Optional<Weekday> get_locale_first_day(StringView locale)
{
return find_regional_values_for_locale(locale, get_regional_first_day);
}
Optional<WeekendStartRegion> __attribute__((weak)) weekend_start_region_from_string(StringView) { return {}; }
Optional<Weekday> __attribute__((weak)) get_regional_weekend_start(StringView) { return {}; }
Optional<Weekday> get_locale_weekend_start(StringView locale)
{
return find_regional_values_for_locale(locale, get_regional_weekend_start);
}
Optional<WeekendEndRegion> __attribute__((weak)) weekend_end_region_from_string(StringView) { return {}; }
Optional<Weekday> __attribute__((weak)) get_regional_weekend_end(StringView) { return {}; }
Optional<Weekday> get_locale_weekend_end(StringView locale)
{
return find_regional_values_for_locale(locale, get_regional_weekend_end);
}
String combine_skeletons(StringView first, StringView second)
{
// https://unicode.org/reports/tr35/tr35-dates.html#availableFormats_appendItems