diff --git a/src/common/bcp47.cpp b/src/common/bcp47.cpp index b230164a0..d13165138 100644 --- a/src/common/bcp47.cpp +++ b/src/common/bcp47.cpp @@ -28,6 +28,12 @@ namespace mtx::bcp47 { +bool +operator <(language_c::extension_t const &a, + language_c::extension_t const &b) { + return mtx::string::to_lower_ascii(a.singleton) < mtx::string::to_lower_ascii(b.singleton); +} + bool language_c::ms_disabled = false; language_c::extension_t::extension_t(std::string const &singleton_, @@ -255,6 +261,8 @@ language_c::parse_extensions(std::string const &str) { else m_extensions.back().extensions.emplace_back(part); + std::sort(m_extensions.begin(), m_extensions.end()); + return validate_extensions(); } @@ -543,7 +551,8 @@ language_c::add_extension(extension_t const &extension) { for (auto const &extension_subtag : extension.extensions) extensions_lower.emplace_back(mtx::string::to_lower_ascii(extension_subtag)); - m_extensions.emplace_back(extension_t{ mtx::string::to_lower_ascii(extension.singleton), extensions_lower }); + auto cleaned_extension = extension_t{ mtx::string::to_lower_ascii(extension.singleton), extensions_lower }; + m_extensions.insert(std::lower_bound(m_extensions.begin(), m_extensions.end(), cleaned_extension), cleaned_extension); m_formatted_up_to_date = false; diff --git a/tests/unit/common/bcp47.cpp b/tests/unit/common/bcp47.cpp index b41a4b904..6bdd28112 100644 --- a/tests/unit/common/bcp47.cpp +++ b/tests/unit/common/bcp47.cpp @@ -329,4 +329,9 @@ TEST(BCP47LanguageTags, ExtensionsRFC6497) { EXPECT_TRUE(mtx::bcp47::language_c::parse("ja-t-it-m0-xxx-v21a-2007").is_valid()); } +TEST(BCP47LanguageTags, ExtensionsFormatting) { + EXPECT_EQ("ja-t-test-u-attr-co-phonebk"s, mtx::bcp47::language_c::parse("ja-T-Test-U-AttR-CO-phoNEbk").format()); + EXPECT_EQ("ja-t-test-u-attr-co-phonebk"s, mtx::bcp47::language_c::parse("ja-U-AttR-CO-phoNEbk-T-Test").format()); +} + }