From a77f323dfb00212e0c705209efa0155320b0256a Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Thu, 2 Sep 2021 21:44:12 -0400 Subject: [PATCH] LibUnicode: Implement the Remove Likely Subtags method Unlike Add Likely Subtags, this method doesn't require generated data. Instead, it is defined in terms of Add Likely Subtags. --- Userland/Libraries/LibUnicode/Locale.cpp | 46 ++++++++++++++++++++++++ Userland/Libraries/LibUnicode/Locale.h | 2 ++ 2 files changed, 48 insertions(+) diff --git a/Userland/Libraries/LibUnicode/Locale.cpp b/Userland/Libraries/LibUnicode/Locale.cpp index e1714299ae7..b1ef307aed4 100644 --- a/Userland/Libraries/LibUnicode/Locale.cpp +++ b/Userland/Libraries/LibUnicode/Locale.cpp @@ -843,6 +843,52 @@ Optional add_likely_subtags([[maybe_unused]] LanguageID const& langu #endif } +Optional remove_likely_subtags([[maybe_unused]] LanguageID const& language_id) +{ +#if ENABLE_UNICODE_DATA + // https://www.unicode.org/reports/tr35/#Likely_Subtags + auto return_language_and_variants = [](auto language, auto variants) { + language.variants = move(variants); + return language; + }; + + // 1. First get max = AddLikelySubtags(inputLocale). If an error is signaled, return it. + auto maximized = add_likely_subtags(language_id); + if (!maximized.has_value()) + return {}; + + // 2. Remove the variants from max. + auto variants = move(maximized->variants); + + // 3. Get the components of the max (languagemax, scriptmax, regionmax). + auto language_max = maximized->language; + auto script_max = maximized->script; + auto region_max = maximized->region; + + // 4. Then for trial in {languagemax, languagemax_regionmax, languagemax_scriptmax}: + // If AddLikelySubtags(trial) = max, then return trial + variants. + auto run_trial = [&](Optional language, Optional script, Optional region) -> Optional { + LanguageID trial { .language = move(language), .script = move(script), .region = move(region) }; + + if (add_likely_subtags(trial) == maximized) + return return_language_and_variants(move(trial), move(variants)); + return {}; + }; + + if (auto trial = run_trial(language_max, {}, {}); trial.has_value()) + return trial; + if (auto trial = run_trial(language_max, {}, region_max); trial.has_value()) + return trial; + if (auto trial = run_trial(language_max, script_max, {}); trial.has_value()) + return trial; + + // 5. If you do not get a match, return max + variants. + return return_language_and_variants(maximized.release_value(), move(variants)); +#else + return {}; +#endif +} + String resolve_most_likely_territory([[maybe_unused]] LanguageID const& language_id, StringView territory_alias) { auto aliases = territory_alias.split_view(' '); diff --git a/Userland/Libraries/LibUnicode/Locale.h b/Userland/Libraries/LibUnicode/Locale.h index 08498026aec..c1ad4588074 100644 --- a/Userland/Libraries/LibUnicode/Locale.h +++ b/Userland/Libraries/LibUnicode/Locale.h @@ -18,6 +18,7 @@ namespace Unicode { struct LanguageID { String to_string() const; + bool operator==(LanguageID const&) const = default; bool is_root { false }; Optional language {}; @@ -131,6 +132,7 @@ Optional resolve_variant_alias(StringView variant); Optional resolve_subdivision_alias(StringView subdivision); Optional add_likely_subtags(LanguageID const& language_id); +Optional remove_likely_subtags(LanguageID const& language_id); String resolve_most_likely_territory(LanguageID const& language_id, StringView territory_alias); }