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.
This commit is contained in:
Timothy Flynn 2021-09-02 21:44:12 -04:00 committed by Linus Groh
parent 0b1f5118d5
commit a77f323dfb
Notes: sideshowbarker 2024-07-18 08:59:31 +09:00
2 changed files with 48 additions and 0 deletions

View file

@ -843,6 +843,52 @@ Optional<LanguageID> add_likely_subtags([[maybe_unused]] LanguageID const& langu
#endif #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) String resolve_most_likely_territory([[maybe_unused]] LanguageID const& language_id, StringView territory_alias)
{ {
auto aliases = territory_alias.split_view(' '); auto aliases = territory_alias.split_view(' ');

View file

@ -18,6 +18,7 @@ namespace Unicode {
struct LanguageID { struct LanguageID {
String to_string() const; String to_string() const;
bool operator==(LanguageID const&) const = default;
bool is_root { false }; bool is_root { false };
Optional<String> language {}; Optional<String> language {};
@ -131,6 +132,7 @@ Optional<StringView> resolve_variant_alias(StringView variant);
Optional<StringView> resolve_subdivision_alias(StringView subdivision); Optional<StringView> resolve_subdivision_alias(StringView subdivision);
Optional<LanguageID> add_likely_subtags(LanguageID const& language_id); 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); String resolve_most_likely_territory(LanguageID const& language_id, StringView territory_alias);
} }