summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibUnicode
diff options
context:
space:
mode:
authorTimothy Flynn <trflynn89@pm.me>2021-09-02 21:44:12 -0400
committerLinus Groh <mail@linusgroh.de>2021-09-04 13:51:40 +0100
commita77f323dfb00212e0c705209efa0155320b0256a (patch)
tree663ba02d888c447018014b53f24caf22dc4e52d5 /Userland/Libraries/LibUnicode
parent0b1f5118d568e3c7a326ea0f0e8c29edc90e13a0 (diff)
downloadserenity-a77f323dfb00212e0c705209efa0155320b0256a.zip
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.
Diffstat (limited to 'Userland/Libraries/LibUnicode')
-rw-r--r--Userland/Libraries/LibUnicode/Locale.cpp46
-rw-r--r--Userland/Libraries/LibUnicode/Locale.h2
2 files changed, 48 insertions, 0 deletions
diff --git a/Userland/Libraries/LibUnicode/Locale.cpp b/Userland/Libraries/LibUnicode/Locale.cpp
index e1714299ae..b1ef307aed 100644
--- a/Userland/Libraries/LibUnicode/Locale.cpp
+++ b/Userland/Libraries/LibUnicode/Locale.cpp
@@ -843,6 +843,52 @@ Optional<LanguageID> add_likely_subtags([[maybe_unused]] LanguageID const& langu
#endif
}
+Optional<LanguageID> 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<String> language, Optional<String> script, Optional<String> region) -> Optional<LanguageID> {
+ 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 08498026ae..c1ad458807 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<String> language {};
@@ -131,6 +132,7 @@ Optional<StringView> resolve_variant_alias(StringView variant);
Optional<StringView> resolve_subdivision_alias(StringView subdivision);
Optional<LanguageID> add_likely_subtags(LanguageID const& language_id);
+Optional<LanguageID> remove_likely_subtags(LanguageID const& language_id);
String resolve_most_likely_territory(LanguageID const& language_id, StringView territory_alias);
}