summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimothy Flynn <trflynn89@pm.me>2023-01-16 11:28:27 -0500
committerTim Flynn <trflynn89@pm.me>2023-01-16 18:33:44 -0500
commitd6ddca0c0f1f6d3a86672a5bb04d2fb56377beff (patch)
tree8ad3dec13dbabbec70766905475c556d63113bd2
parentbc51017a03087057dc8e8f437b4049f2ab7ebba1 (diff)
downloadserenity-d6ddca0c0f1f6d3a86672a5bb04d2fb56377beff.zip
AK+LibUnicode: Provide Unicode-aware String titlecase transformation
-rw-r--r--AK/String.h4
-rw-r--r--Tests/AK/TestString.cpp24
-rw-r--r--Userland/Libraries/LibUnicode/String.cpp7
3 files changed, 33 insertions, 2 deletions
diff --git a/AK/String.h b/AK/String.h
index 9fdb05b68d..1a19b6f429 100644
--- a/AK/String.h
+++ b/AK/String.h
@@ -45,10 +45,10 @@ public:
// Creates a new String from a sequence of UTF-8 encoded code points.
static ErrorOr<String> from_utf8(StringView);
- // Creates a new String by transforming this String to lower- or uppercase. Using these methods
- // require linking LibUnicode into your application.
+ // Creates a new String by case-transforming this String. Using these methods require linking LibUnicode into your application.
ErrorOr<String> to_lowercase(Optional<StringView> const& locale = {}) const;
ErrorOr<String> to_uppercase(Optional<StringView> const& locale = {}) const;
+ ErrorOr<String> to_titlecase(Optional<StringView> const& locale = {}) const;
// Creates a substring with a deep copy of the specified data window.
ErrorOr<String> substring_from_byte_offset(size_t start, size_t byte_count) const;
diff --git a/Tests/AK/TestString.cpp b/Tests/AK/TestString.cpp
index 727b30190e..42f5ffc63f 100644
--- a/Tests/AK/TestString.cpp
+++ b/Tests/AK/TestString.cpp
@@ -163,6 +163,30 @@ TEST_CASE(to_uppercase)
}
}
+TEST_CASE(to_titlecase)
+{
+ {
+ auto string = MUST(String::from_utf8("foo bar baz"sv));
+ auto result = MUST(string.to_titlecase());
+ EXPECT_EQ(result, "Foo Bar Baz"sv);
+ }
+ {
+ auto string = MUST(String::from_utf8("foo \n \r bar \t baz"sv));
+ auto result = MUST(string.to_titlecase());
+ EXPECT_EQ(result, "Foo \n \r Bar \t Baz"sv);
+ }
+ {
+ auto string = MUST(String::from_utf8("f\"oo\" b'ar'"sv));
+ auto result = MUST(string.to_titlecase());
+ EXPECT_EQ(result, "F\"Oo\" B'Ar'"sv);
+ }
+ {
+ auto string = MUST(String::from_utf8("123dollars"sv));
+ auto result = MUST(string.to_titlecase());
+ EXPECT_EQ(result, "123Dollars"sv);
+ }
+}
+
TEST_CASE(is_one_of)
{
auto foo = MUST(String::from_utf8("foo"sv));
diff --git a/Userland/Libraries/LibUnicode/String.cpp b/Userland/Libraries/LibUnicode/String.cpp
index 4cbc47d5ad..5251d310bd 100644
--- a/Userland/Libraries/LibUnicode/String.cpp
+++ b/Userland/Libraries/LibUnicode/String.cpp
@@ -26,4 +26,11 @@ ErrorOr<String> String::to_uppercase(Optional<StringView> const& locale) const
return builder.to_string();
}
+ErrorOr<String> String::to_titlecase(Optional<StringView> const& locale) const
+{
+ StringBuilder builder;
+ TRY(Unicode::Detail::build_titlecase_string(code_points(), builder, locale));
+ return builder.to_string();
+}
+
}