Browse Source

LibUnicode: Add method to combine two format pattern skeletons

The fields of the generated elements must be in the same order as the
table here:
https://unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table

Further, only one field from each group of fields is allowed.
Timothy Flynn 3 years ago
parent
commit
2024d9e9ea

+ 43 - 0
Userland/Libraries/LibUnicode/DateTimeFormat.cpp

@@ -4,6 +4,8 @@
  * SPDX-License-Identifier: BSD-2-Clause
  */
 
+#include <AK/Array.h>
+#include <AK/StringBuilder.h>
 #include <LibUnicode/DateTimeFormat.h>
 #include <LibUnicode/Locale.h>
 
@@ -113,6 +115,47 @@ Optional<Unicode::HourCycle> get_default_regional_hour_cycle(StringView locale)
     return {};
 }
 
+String combine_skeletons(StringView first, StringView second)
+{
+    // https://unicode.org/reports/tr35/tr35-dates.html#availableFormats_appendItems
+    constexpr auto field_order = Array {
+        "G"sv,       // Era
+        "yYuUr"sv,   // Year
+        "ML"sv,      // Month
+        "dDFg"sv,    // Day
+        "Eec"sv,     // Weekday
+        "abB"sv,     // Period
+        "hHKk"sv,    // Hour
+        "m"sv,       // Minute
+        "sSA"sv,     // Second
+        "zZOvVXx"sv, // Zone
+    };
+
+    StringBuilder builder;
+
+    auto append_from_skeleton = [&](auto skeleton, auto ch) {
+        auto first_index = skeleton.find(ch);
+        if (!first_index.has_value())
+            return false;
+
+        auto last_index = skeleton.find_last(ch);
+
+        builder.append(skeleton.substring_view(*first_index, *last_index - *first_index + 1));
+        return true;
+    };
+
+    for (auto fields : field_order) {
+        for (auto ch : fields) {
+            if (append_from_skeleton(first, ch))
+                break;
+            if (append_from_skeleton(second, ch))
+                break;
+        }
+    }
+
+    return builder.build();
+}
+
 Optional<CalendarFormat> get_calendar_format([[maybe_unused]] StringView locale, [[maybe_unused]] StringView calendar, [[maybe_unused]] CalendarFormatType type)
 {
 #if ENABLE_UNICODE_DATA

+ 1 - 0
Userland/Libraries/LibUnicode/DateTimeFormat.h

@@ -157,6 +157,7 @@ CalendarPatternStyle calendar_pattern_style_from_string(StringView style);
 StringView calendar_pattern_style_to_string(CalendarPatternStyle style);
 Vector<Unicode::HourCycle> get_regional_hour_cycles(StringView locale);
 Optional<Unicode::HourCycle> get_default_regional_hour_cycle(StringView locale);
+String combine_skeletons(StringView first, StringView second);
 Optional<CalendarFormat> get_calendar_format(StringView locale, StringView calendar, CalendarFormatType type);
 Vector<CalendarPattern> get_calendar_available_formats(StringView locale, StringView calendar);
 Optional<Unicode::CalendarRangePattern> get_calendar_default_range_format(StringView locale, StringView calendar);