123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- /*
- * Copyright (c) 2024, Tim Flynn <trflynn89@serenityos.org>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
- #define AK_DONT_REPLACE_STD
- #include <AK/Array.h>
- #include <LibUnicode/DisplayNames.h>
- #include <LibUnicode/ICU.h>
- #include <unicode/dtptngen.h>
- #include <unicode/localebuilder.h>
- #include <unicode/locdspnm.h>
- #include <unicode/tznames.h>
- #include <unicode/udatpg.h>
- namespace Unicode {
- LanguageDisplay language_display_from_string(StringView language_display)
- {
- if (language_display == "standard"sv)
- return LanguageDisplay::Standard;
- if (language_display == "dialect"sv)
- return LanguageDisplay::Dialect;
- VERIFY_NOT_REACHED();
- }
- StringView language_display_to_string(LanguageDisplay language_display)
- {
- switch (language_display) {
- case LanguageDisplay::Standard:
- return "standard"sv;
- case LanguageDisplay::Dialect:
- return "dialect"sv;
- default:
- VERIFY_NOT_REACHED();
- }
- }
- Optional<String> language_display_name(StringView locale, StringView language, LanguageDisplay display)
- {
- auto locale_data = LocaleData::for_locale(locale);
- if (!locale_data.has_value())
- return {};
- auto language_data = LocaleData::for_locale(language);
- if (!language_data.has_value())
- return {};
- auto& display_names = display == LanguageDisplay::Standard
- ? locale_data->standard_display_names()
- : locale_data->dialect_display_names();
- icu::UnicodeString result;
- display_names.localeDisplayName(language_data->locale().getName(), result);
- return icu_string_to_string(result);
- }
- Optional<String> region_display_name(StringView locale, StringView region)
- {
- UErrorCode status = U_ZERO_ERROR;
- auto locale_data = LocaleData::for_locale(locale);
- if (!locale_data.has_value())
- return {};
- auto icu_region = icu::LocaleBuilder().setRegion(icu_string_piece(region)).build(status);
- if (icu_failure(status))
- return {};
- icu::UnicodeString result;
- locale_data->standard_display_names().regionDisplayName(icu_region.getCountry(), result);
- return icu_string_to_string(result);
- }
- Optional<String> script_display_name(StringView locale, StringView script)
- {
- UErrorCode status = U_ZERO_ERROR;
- auto locale_data = LocaleData::for_locale(locale);
- if (!locale_data.has_value())
- return {};
- auto icu_script = icu::LocaleBuilder().setScript(icu_string_piece(script)).build(status);
- if (icu_failure(status))
- return {};
- icu::UnicodeString result;
- locale_data->standard_display_names().scriptDisplayName(icu_script.getScript(), result);
- return icu_string_to_string(result);
- }
- Optional<String> calendar_display_name(StringView locale, StringView calendar)
- {
- auto locale_data = LocaleData::for_locale(locale);
- if (!locale_data.has_value())
- return {};
- if (calendar == "gregory"sv)
- calendar = "gregorian"sv;
- if (calendar == "islamicc"sv)
- calendar = "islamic-civil"sv;
- if (calendar == "ethioaa"sv)
- calendar = "ethiopic-amete-alem"sv;
- icu::UnicodeString result;
- locale_data->standard_display_names().keyValueDisplayName("calendar", ByteString(calendar).characters(), result);
- return icu_string_to_string(result);
- }
- static constexpr UDateTimePatternField icu_date_time_field(StringView field)
- {
- if (field == "day"sv)
- return UDATPG_DAY_FIELD;
- if (field == "dayPeriod"sv)
- return UDATPG_DAYPERIOD_FIELD;
- if (field == "era"sv)
- return UDATPG_ERA_FIELD;
- if (field == "hour"sv)
- return UDATPG_HOUR_FIELD;
- if (field == "minute"sv)
- return UDATPG_MINUTE_FIELD;
- if (field == "month"sv)
- return UDATPG_MONTH_FIELD;
- if (field == "quarter"sv)
- return UDATPG_QUARTER_FIELD;
- if (field == "second"sv)
- return UDATPG_SECOND_FIELD;
- if (field == "timeZoneName"sv)
- return UDATPG_ZONE_FIELD;
- if (field == "weekOfYear"sv)
- return UDATPG_WEEK_OF_YEAR_FIELD;
- if (field == "weekday"sv)
- return UDATPG_WEEKDAY_FIELD;
- if (field == "year"sv)
- return UDATPG_YEAR_FIELD;
- VERIFY_NOT_REACHED();
- }
- static constexpr UDateTimePGDisplayWidth icu_date_time_style(Style style)
- {
- switch (style) {
- case Style::Long:
- return UDATPG_WIDE;
- case Style::Short:
- return UDATPG_ABBREVIATED;
- case Style::Narrow:
- return UDATPG_NARROW;
- }
- VERIFY_NOT_REACHED();
- }
- Optional<String> date_time_field_display_name(StringView locale, StringView field, Style style)
- {
- auto locale_data = LocaleData::for_locale(locale);
- if (!locale_data.has_value())
- return {};
- auto icu_field = icu_date_time_field(field);
- auto icu_style = icu_date_time_style(style);
- icu::UnicodeString result;
- result = locale_data->date_time_pattern_generator().getFieldDisplayName(icu_field, icu_style);
- return icu_string_to_string(result);
- }
- Optional<String> time_zone_display_name(StringView locale, StringView time_zone_identifier, TimeZone::InDST in_dst, double time)
- {
- auto locale_data = LocaleData::for_locale(locale);
- if (!locale_data.has_value())
- return {};
- icu::UnicodeString time_zone_name;
- auto type = in_dst == TimeZone::InDST::Yes ? UTZNM_LONG_DAYLIGHT : UTZNM_LONG_STANDARD;
- locale_data->time_zone_names().getDisplayName(icu_string(time_zone_identifier), type, time, time_zone_name);
- if (static_cast<bool>(time_zone_name.isBogus()))
- return {};
- return icu_string_to_string(time_zone_name);
- }
- static constexpr Array<UChar, 4> icu_currency_code(StringView currency)
- {
- VERIFY(currency.length() == 3);
- return to_array({
- static_cast<UChar>(currency[0]),
- static_cast<UChar>(currency[1]),
- static_cast<UChar>(currency[2]),
- u'\0',
- });
- }
- static constexpr UCurrNameStyle icu_currency_style(Style style)
- {
- switch (style) {
- case Style::Long:
- return UCURR_LONG_NAME;
- case Style::Short:
- return UCURR_SYMBOL_NAME;
- case Style::Narrow:
- return UCURR_NARROW_SYMBOL_NAME;
- }
- VERIFY_NOT_REACHED();
- }
- Optional<String> currency_display_name(StringView locale, StringView currency, Style style)
- {
- UErrorCode status = U_ZERO_ERROR;
- auto locale_data = LocaleData::for_locale(locale);
- if (!locale_data.has_value())
- return {};
- auto icu_currency = icu_currency_code(currency);
- i32 length = 0;
- UChar const* result = ucurr_getName(icu_currency.data(), locale_data->locale().getName(), icu_currency_style(style), nullptr, &length, &status);
- if (icu_failure(status))
- return {};
- if ((status == U_USING_DEFAULT_WARNING) && (result == icu_currency.data()))
- return {};
- return icu_string_to_string(result, length);
- }
- Optional<String> currency_numeric_display_name(StringView locale, StringView currency)
- {
- UErrorCode status = U_ZERO_ERROR;
- auto locale_data = LocaleData::for_locale(locale);
- if (!locale_data.has_value())
- return {};
- auto icu_currency = icu_currency_code(currency);
- i32 length = 0;
- UChar const* result = ucurr_getPluralName(icu_currency.data(), locale_data->locale().getName(), nullptr, "other", &length, &status);
- if (icu_failure(status))
- return {};
- if ((status == U_USING_DEFAULT_WARNING) && (result == icu_currency.data()))
- return {};
- return icu_string_to_string(result, length);
- }
- }
|