mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 18:32:45 +00:00 
			
		
		
		
	LibJS+LibLocale: Port Intl.DateTimeFormat to String
This commit is contained in:
		
							parent
							
								
									970e9df245
								
							
						
					
					
						commit
						b2097f4059
					
				
					 8 changed files with 223 additions and 197 deletions
				
			
		|  | @ -715,7 +715,7 @@ static constexpr auto is_char(char ch) | |||
| // "{hour}:{minute} {ampm}" becomes "{hour}:{minute}" (remove the space before {ampm})
 | ||||
| // "{ampm} {hour}" becomes "{hour}" (remove the space after {ampm})
 | ||||
| // "{hour}:{minute} {ampm} {timeZoneName}" becomes "{hour}:{minute} {timeZoneName}" (remove one of the spaces around {ampm})
 | ||||
| static DeprecatedString remove_period_from_pattern(DeprecatedString pattern) | ||||
| static ErrorOr<String> remove_period_from_pattern(String pattern) | ||||
| { | ||||
|     auto is_surrounding_space = [&](auto code_point_iterator) { | ||||
|         if (code_point_iterator.done()) | ||||
|  | @ -738,7 +738,7 @@ static DeprecatedString remove_period_from_pattern(DeprecatedString pattern) | |||
|     }; | ||||
| 
 | ||||
|     for (auto remove : AK::Array { "({ampm})"sv, "{ampm}"sv, "({dayPeriod})"sv, "{dayPeriod}"sv }) { | ||||
|         auto index = pattern.find(remove); | ||||
|         auto index = pattern.find_byte_offset(remove); | ||||
|         if (!index.has_value()) | ||||
|             continue; | ||||
| 
 | ||||
|  | @ -751,25 +751,27 @@ static DeprecatedString remove_period_from_pattern(DeprecatedString pattern) | |||
|         if (auto it = utf8_pattern.iterator_at_byte_offset(*index + remove.length()); it != utf8_pattern.end()) | ||||
|             after_removal = it; | ||||
| 
 | ||||
|         auto pattern_view = pattern.bytes_as_string_view(); | ||||
| 
 | ||||
|         if (is_surrounding_space(before_removal) && !is_opening(after_removal)) { | ||||
|             pattern = DeprecatedString::formatted("{}{}", | ||||
|                 pattern.substring_view(0, *index - before_removal.underlying_code_point_length_in_bytes()), | ||||
|                 pattern.substring_view(*index + remove.length())); | ||||
|             pattern = TRY(String::formatted("{}{}", | ||||
|                 pattern_view.substring_view(0, *index - before_removal.underlying_code_point_length_in_bytes()), | ||||
|                 pattern_view.substring_view(*index + remove.length()))); | ||||
|         } else if (is_surrounding_space(after_removal) && !is_closing(before_removal)) { | ||||
|             pattern = DeprecatedString::formatted("{}{}", | ||||
|                 pattern.substring_view(0, *index), | ||||
|                 pattern.substring_view(*index + remove.length() + after_removal.underlying_code_point_length_in_bytes())); | ||||
|             pattern = TRY(String::formatted("{}{}", | ||||
|                 pattern_view.substring_view(0, *index), | ||||
|                 pattern_view.substring_view(*index + remove.length() + after_removal.underlying_code_point_length_in_bytes()))); | ||||
|         } else { | ||||
|             pattern = DeprecatedString::formatted("{}{}", | ||||
|                 pattern.substring_view(0, *index), | ||||
|                 pattern.substring_view(*index + remove.length())); | ||||
|             pattern = TRY(String::formatted("{}{}", | ||||
|                 pattern_view.substring_view(0, *index), | ||||
|                 pattern_view.substring_view(*index + remove.length()))); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return pattern; | ||||
| } | ||||
| 
 | ||||
| static Optional<CalendarPattern> parse_date_time_pattern_raw(DeprecatedString pattern, DeprecatedString skeleton, CLDR& cldr) | ||||
| static ErrorOr<Optional<CalendarPattern>> parse_date_time_pattern_raw(DeprecatedString pattern, DeprecatedString skeleton, CLDR& cldr) | ||||
| { | ||||
|     // https://unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
 | ||||
|     using Locale::CalendarPatternStyle; | ||||
|  | @ -819,7 +821,7 @@ static Optional<CalendarPattern> parse_date_time_pattern_raw(DeprecatedString pa | |||
|         // Quarter
 | ||||
|         else if (all_of(segment, is_any_of("qQ"sv))) { | ||||
|             // Intl.DateTimeFormat does not support quarter formatting, so drop these patterns.
 | ||||
|             return {}; | ||||
|             return OptionalNone {}; | ||||
|         } | ||||
| 
 | ||||
|         // Month
 | ||||
|  | @ -838,13 +840,13 @@ static Optional<CalendarPattern> parse_date_time_pattern_raw(DeprecatedString pa | |||
|                 format.month = CalendarPatternStyle::Narrow; | ||||
|         } else if (all_of(segment, is_char('l'))) { | ||||
|             // Using 'l' for month formatting is deprecated by TR-35, ensure it is not used.
 | ||||
|             return {}; | ||||
|             return OptionalNone {}; | ||||
|         } | ||||
| 
 | ||||
|         // Week
 | ||||
|         else if (all_of(segment, is_any_of("wW"sv))) { | ||||
|             // Intl.DateTimeFormat does not support week formatting, so drop these patterns.
 | ||||
|             return {}; | ||||
|             return OptionalNone {}; | ||||
|         } | ||||
| 
 | ||||
|         // Day
 | ||||
|  | @ -876,7 +878,7 @@ static Optional<CalendarPattern> parse_date_time_pattern_raw(DeprecatedString pa | |||
|             // TR-35 defines "e", "c", and "cc" as as numeric, and "ee" as 2-digit, but those
 | ||||
|             // pattern styles are not supported by Intl.DateTimeFormat.
 | ||||
|             if (segment.length() <= 2) | ||||
|                 return {}; | ||||
|                 return OptionalNone {}; | ||||
| 
 | ||||
|             if (segment.length() == 4) | ||||
|                 format.weekday = CalendarPatternStyle::Long; | ||||
|  | @ -915,7 +917,7 @@ static Optional<CalendarPattern> parse_date_time_pattern_raw(DeprecatedString pa | |||
|                 format.hour = CalendarPatternStyle::TwoDigit; | ||||
|         } else if (all_of(segment, is_any_of("jJC"sv))) { | ||||
|             // TR-35 indicates these should not be used.
 | ||||
|             return {}; | ||||
|             return OptionalNone {}; | ||||
|         } | ||||
| 
 | ||||
|         // Minute
 | ||||
|  | @ -943,7 +945,7 @@ static Optional<CalendarPattern> parse_date_time_pattern_raw(DeprecatedString pa | |||
|             format.fractional_second_digits = static_cast<u8>(segment.length()); | ||||
|         } else if (all_of(segment, is_char('A'))) { | ||||
|             // Intl.DateTimeFormat does not support millisecond formatting, so drop these patterns.
 | ||||
|             return {}; | ||||
|             return OptionalNone {}; | ||||
|         } | ||||
| 
 | ||||
|         // Zone
 | ||||
|  | @ -976,30 +978,30 @@ static Optional<CalendarPattern> parse_date_time_pattern_raw(DeprecatedString pa | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pattern = builder.build(); | ||||
|     auto parsed_pattern = TRY(builder.to_string()); | ||||
| 
 | ||||
|     if (hour12) { | ||||
|         format.pattern = remove_period_from_pattern(pattern); | ||||
|         format.pattern12 = move(pattern); | ||||
|         format.pattern = TRY(remove_period_from_pattern(parsed_pattern)); | ||||
|         format.pattern12 = move(parsed_pattern); | ||||
|     } else { | ||||
|         format.pattern = move(pattern); | ||||
|         format.pattern = move(parsed_pattern); | ||||
|     } | ||||
| 
 | ||||
|     return format; | ||||
| } | ||||
| 
 | ||||
| static Optional<size_t> parse_date_time_pattern(DeprecatedString pattern, DeprecatedString skeleton, CLDR& cldr) | ||||
| static ErrorOr<Optional<size_t>> parse_date_time_pattern(DeprecatedString pattern, DeprecatedString skeleton, CLDR& cldr) | ||||
| { | ||||
|     auto format = parse_date_time_pattern_raw(move(pattern), move(skeleton), cldr); | ||||
|     auto format = TRY(parse_date_time_pattern_raw(move(pattern), move(skeleton), cldr)); | ||||
|     if (!format.has_value()) | ||||
|         return {}; | ||||
|         return OptionalNone {}; | ||||
| 
 | ||||
|     format->pattern_index = cldr.unique_strings.ensure(move(format->pattern)); | ||||
|     format->pattern_index = cldr.unique_strings.ensure(format->pattern.to_deprecated_string()); | ||||
| 
 | ||||
|     if (format->pattern12.has_value()) | ||||
|         format->pattern12_index = cldr.unique_strings.ensure(format->pattern12.release_value()); | ||||
|         format->pattern12_index = cldr.unique_strings.ensure(format->pattern12->to_deprecated_string()); | ||||
| 
 | ||||
|     return cldr.unique_patterns.ensure(format.release_value()); | ||||
|     return Optional<size_t> { cldr.unique_patterns.ensure(format.release_value()) }; | ||||
| } | ||||
| 
 | ||||
| template<typename... Chars> | ||||
|  | @ -1008,7 +1010,7 @@ static constexpr bool char_is_one_of(char ch, Chars&&... chars) | |||
|     return ((ch == chars) || ...); | ||||
| } | ||||
| 
 | ||||
| static void parse_interval_patterns(Calendar& calendar, JsonObject const& interval_formats_object, CLDR& cldr) | ||||
| static ErrorOr<void> parse_interval_patterns(Calendar& calendar, JsonObject const& interval_formats_object, CLDR& cldr) | ||||
| { | ||||
|     // https://unicode.org/reports/tr35/tr35-dates.html#intervalFormats
 | ||||
|     CalendarRangePatternList range_formats {}; | ||||
|  | @ -1060,28 +1062,29 @@ static void parse_interval_patterns(Calendar& calendar, JsonObject const& interv | |||
|         HashMap<StringView, size_t> partitions; | ||||
|         StringView last_partition; | ||||
| 
 | ||||
|         auto begin_index = pattern.find('{'); | ||||
|         auto begin_index = pattern.find_byte_offset('{'); | ||||
|         size_t end_index = 0; | ||||
| 
 | ||||
|         while (begin_index.has_value()) { | ||||
|             end_index = pattern.find('}', *begin_index).value(); | ||||
|             end_index = pattern.find_byte_offset('}', *begin_index).value(); | ||||
| 
 | ||||
|             auto partition = pattern.substring_view(*begin_index, end_index - *begin_index); | ||||
|             auto partition = pattern.bytes_as_string_view().substring_view(*begin_index, end_index - *begin_index); | ||||
|             if (partitions.contains(partition)) | ||||
|                 break; | ||||
| 
 | ||||
|             partitions.set(partition, *begin_index); | ||||
|             last_partition = partition; | ||||
| 
 | ||||
|             begin_index = pattern.find('{', end_index + 1); | ||||
|             begin_index = pattern.find_byte_offset('{', end_index + 1); | ||||
|         } | ||||
| 
 | ||||
|         VERIFY(begin_index.has_value() && !last_partition.is_empty()); | ||||
|         auto start_range_end = partitions.get(last_partition).value() + last_partition.length() + 1; | ||||
| 
 | ||||
|         auto start_range = pattern.substring_view(0, start_range_end); | ||||
|         auto separator = pattern.substring_view(start_range_end, *begin_index - start_range_end); | ||||
|         auto end_range = pattern.substring_view(*begin_index); | ||||
|         auto pattern_view = pattern.bytes_as_string_view(); | ||||
|         auto start_range = pattern_view.substring_view(0, start_range_end); | ||||
|         auto separator = pattern_view.substring_view(start_range_end, *begin_index - start_range_end); | ||||
|         auto end_range = pattern_view.substring_view(*begin_index); | ||||
| 
 | ||||
|         CalendarRangePattern format {}; | ||||
|         format.skeleton_index = cldr.unique_strings.ensure(skeleton); | ||||
|  | @ -1097,21 +1100,21 @@ static void parse_interval_patterns(Calendar& calendar, JsonObject const& interv | |||
|         return format; | ||||
|     }; | ||||
| 
 | ||||
|     interval_formats_object.for_each_member([&](auto const& skeleton, auto const& value) { | ||||
|     TRY(interval_formats_object.try_for_each_member([&](auto const& skeleton, auto const& value) -> ErrorOr<void> { | ||||
|         if (skeleton == "intervalFormatFallback"sv) { | ||||
|             auto range_format = split_default_range_pattern(skeleton, value.as_string()); | ||||
|             calendar.default_range_format = cldr.unique_range_patterns.ensure(move(range_format)); | ||||
|             return; | ||||
|             return {}; | ||||
|         } | ||||
| 
 | ||||
|         value.as_object().for_each_member([&](auto const& field, auto const& pattern) { | ||||
|         TRY(value.as_object().try_for_each_member([&](auto const& field, auto const& pattern) -> ErrorOr<void> { | ||||
|             if (field.ends_with("alt-variant"sv)) | ||||
|                 return; | ||||
|                 return {}; | ||||
| 
 | ||||
|             VERIFY(field.length() == 1); | ||||
|             auto name = name_of_field(field[0]); | ||||
| 
 | ||||
|             auto format = parse_date_time_pattern_raw(pattern.as_string(), skeleton, cldr).release_value(); | ||||
|             auto format = TRY(parse_date_time_pattern_raw(pattern.as_string(), skeleton, cldr)).release_value(); | ||||
| 
 | ||||
|             auto range_format = split_range_pattern(skeleton, name, format.pattern, format); | ||||
|             range_formats.append(cldr.unique_range_patterns.ensure(move(range_format))); | ||||
|  | @ -1122,26 +1125,34 @@ static void parse_interval_patterns(Calendar& calendar, JsonObject const& interv | |||
|             } else { | ||||
|                 range12_formats.append(range_formats.last()); | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| 
 | ||||
|             return {}; | ||||
|         })); | ||||
| 
 | ||||
|         return {}; | ||||
|     })); | ||||
| 
 | ||||
|     calendar.range_formats = cldr.unique_range_pattern_lists.ensure(move(range_formats)); | ||||
|     calendar.range12_formats = cldr.unique_range_pattern_lists.ensure(move(range12_formats)); | ||||
| 
 | ||||
|     return {}; | ||||
| } | ||||
| 
 | ||||
| static void generate_default_patterns(CalendarPatternList& formats, CLDR& cldr) | ||||
| static ErrorOr<void> generate_default_patterns(CalendarPatternList& formats, CLDR& cldr) | ||||
| { | ||||
|     // For compatibility with ICU, we generate a list of default patterns for every locale:
 | ||||
|     // https://github.com/unicode-org/icu/blob/release-71-1/icu4c/source/i18n/dtptngen.cpp#L1343-L1354=
 | ||||
|     static constexpr auto default_patterns = Array { "G"sv, "y"sv, "M"sv, "E"sv, "D"sv, "F"sv, "d"sv, "a"sv, "B"sv, "H"sv, "mm"sv, "ss"sv, "SS"sv, "v"sv }; | ||||
| 
 | ||||
|     for (auto pattern : default_patterns) { | ||||
|         auto index = parse_date_time_pattern(pattern, pattern, cldr); | ||||
|         auto index = TRY(parse_date_time_pattern(pattern, pattern, cldr)); | ||||
|         VERIFY(index.has_value()); | ||||
| 
 | ||||
|         if (!formats.contains_slow(*index)) | ||||
|             formats.append(*index); | ||||
|     } | ||||
| 
 | ||||
|     return {}; | ||||
| } | ||||
| 
 | ||||
| static void generate_missing_patterns(Calendar& calendar, CalendarPatternList& formats, Vector<CalendarPattern> date_formats, Vector<CalendarPattern> time_formats, CLDR& cldr) | ||||
|  | @ -1390,12 +1401,12 @@ static ErrorOr<void> parse_calendars(DeprecatedString locale_calendars_path, CLD | |||
|     auto const& dates_object = locale_object.get_object("dates"sv).value(); | ||||
|     auto const& calendars_object = dates_object.get_object("calendars"sv).value(); | ||||
| 
 | ||||
|     auto parse_patterns = [&](auto const& patterns_object, auto const& skeletons_object, Vector<CalendarPattern>* patterns) { | ||||
|         auto parse_pattern = [&](auto name) { | ||||
|     auto parse_patterns = [&](auto const& patterns_object, auto const& skeletons_object, Vector<CalendarPattern>* patterns) -> ErrorOr<size_t> { | ||||
|         auto parse_pattern = [&](auto name) -> ErrorOr<size_t> { | ||||
|             auto format = patterns_object.get_deprecated_string(name); | ||||
|             auto skeleton = skeletons_object.get_deprecated_string(name); | ||||
| 
 | ||||
|             auto format_index = parse_date_time_pattern(format.value(), skeleton.value_or(DeprecatedString::empty()), cldr).value(); | ||||
|             auto format_index = TRY(parse_date_time_pattern(format.value(), skeleton.value_or(DeprecatedString::empty()), cldr)).value(); | ||||
| 
 | ||||
|             if (patterns) | ||||
|                 patterns->append(cldr.unique_patterns.get(format_index)); | ||||
|  | @ -1404,19 +1415,19 @@ static ErrorOr<void> parse_calendars(DeprecatedString locale_calendars_path, CLD | |||
|         }; | ||||
| 
 | ||||
|         CalendarFormat formats {}; | ||||
|         formats.full_format = parse_pattern("full"sv); | ||||
|         formats.long_format = parse_pattern("long"sv); | ||||
|         formats.medium_format = parse_pattern("medium"sv); | ||||
|         formats.short_format = parse_pattern("short"sv); | ||||
|         formats.full_format = TRY(parse_pattern("full"sv)); | ||||
|         formats.long_format = TRY(parse_pattern("long"sv)); | ||||
|         formats.medium_format = TRY(parse_pattern("medium"sv)); | ||||
|         formats.short_format = TRY(parse_pattern("short"sv)); | ||||
| 
 | ||||
|         return cldr.unique_formats.ensure(move(formats)); | ||||
|     }; | ||||
| 
 | ||||
|     calendars_object.for_each_member([&](auto const& calendar_name, JsonValue const& value) { | ||||
|     TRY(calendars_object.try_for_each_member([&](auto const& calendar_name, JsonValue const& value) -> ErrorOr<void> { | ||||
|         // The generic calendar is not a supported Unicode calendar key, so skip it:
 | ||||
|         // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/calendar#unicode_calendar_keys
 | ||||
|         if (calendar_name == "generic"sv) | ||||
|             return; | ||||
|             return {}; | ||||
| 
 | ||||
|         Calendar calendar {}; | ||||
|         CalendarPatternList available_formats {}; | ||||
|  | @ -1429,21 +1440,21 @@ static ErrorOr<void> parse_calendars(DeprecatedString locale_calendars_path, CLD | |||
| 
 | ||||
|         auto const& date_formats_object = value.as_object().get_object("dateFormats"sv).value(); | ||||
|         auto const& date_skeletons_object = value.as_object().get_object("dateSkeletons"sv).value(); | ||||
|         calendar.date_formats = parse_patterns(date_formats_object, date_skeletons_object, &date_formats); | ||||
|         calendar.date_formats = TRY(parse_patterns(date_formats_object, date_skeletons_object, &date_formats)); | ||||
| 
 | ||||
|         auto const& time_formats_object = value.as_object().get_object("timeFormats"sv).value(); | ||||
|         auto const& time_skeletons_object = value.as_object().get_object("timeSkeletons"sv).value(); | ||||
|         calendar.time_formats = parse_patterns(time_formats_object, time_skeletons_object, &time_formats); | ||||
|         calendar.time_formats = TRY(parse_patterns(time_formats_object, time_skeletons_object, &time_formats)); | ||||
| 
 | ||||
|         auto const& standard_date_time_formats_object = value.as_object().get_object("dateTimeFormats-atTime"sv)->get_object("standard"sv).value(); | ||||
|         calendar.date_time_formats = parse_patterns(standard_date_time_formats_object, JsonObject {}, nullptr); | ||||
|         calendar.date_time_formats = TRY(parse_patterns(standard_date_time_formats_object, JsonObject {}, nullptr)); | ||||
| 
 | ||||
|         auto const& date_time_formats_object = value.as_object().get_object("dateTimeFormats"sv).value(); | ||||
|         auto const& available_formats_object = date_time_formats_object.get_object("availableFormats"sv).value(); | ||||
|         available_formats_object.for_each_member([&](auto const& skeleton, JsonValue const& pattern) { | ||||
|             auto pattern_index = parse_date_time_pattern(pattern.as_string(), skeleton, cldr); | ||||
|         TRY(available_formats_object.try_for_each_member([&](auto const& skeleton, JsonValue const& pattern) -> ErrorOr<void> { | ||||
|             auto pattern_index = TRY(parse_date_time_pattern(pattern.as_string(), skeleton, cldr)); | ||||
|             if (!pattern_index.has_value()) | ||||
|                 return; | ||||
|                 return {}; | ||||
| 
 | ||||
|             auto const& format = cldr.unique_patterns.get(*pattern_index); | ||||
|             if (format.contains_only_date_fields()) | ||||
|  | @ -1453,18 +1464,22 @@ static ErrorOr<void> parse_calendars(DeprecatedString locale_calendars_path, CLD | |||
| 
 | ||||
|             if (!available_formats.contains_slow(*pattern_index)) | ||||
|                 available_formats.append(*pattern_index); | ||||
|         }); | ||||
| 
 | ||||
|             return {}; | ||||
|         })); | ||||
| 
 | ||||
|         auto const& interval_formats_object = date_time_formats_object.get_object("intervalFormats"sv).value(); | ||||
|         parse_interval_patterns(calendar, interval_formats_object, cldr); | ||||
|         TRY(parse_interval_patterns(calendar, interval_formats_object, cldr)); | ||||
| 
 | ||||
|         generate_default_patterns(available_formats, cldr); | ||||
|         TRY(generate_default_patterns(available_formats, cldr)); | ||||
|         generate_missing_patterns(calendar, available_formats, move(date_formats), move(time_formats), cldr); | ||||
|         parse_calendar_symbols(calendar, value.as_object(), cldr); | ||||
| 
 | ||||
|         calendar.available_formats = cldr.unique_pattern_lists.ensure(move(available_formats)); | ||||
|         locale.calendars.set(calendar_name, cldr.unique_calendars.ensure(move(calendar))); | ||||
|     }); | ||||
| 
 | ||||
|         return {}; | ||||
|     })); | ||||
| 
 | ||||
|     return {}; | ||||
| } | ||||
|  | @ -1736,7 +1751,9 @@ static ErrorOr<void> generate_unicode_locale_implementation(Core::Stream::Buffer | |||
|     generator.append(R"~~~( | ||||
| #include <AK/Array.h> | ||||
| #include <AK/BinarySearch.h> | ||||
| #include <AK/Error.h> | ||||
| #include <AK/Optional.h> | ||||
| #include <AK/String.h> | ||||
| #include <AK/StringView.h> | ||||
| #include <LibLocale/DateTimeFormat.h> | ||||
| #include <LibLocale/DateTimeFormatData.h> | ||||
|  | @ -1778,13 +1795,13 @@ static void convert_calendar_fields(SourceType const& source, TargetType& target | |||
| } | ||||
| 
 | ||||
| struct CalendarPatternImpl { | ||||
|     CalendarPattern to_unicode_calendar_pattern() const { | ||||
|     ErrorOr<CalendarPattern> to_unicode_calendar_pattern() const { | ||||
|         CalendarPattern calendar_pattern {}; | ||||
| 
 | ||||
|         calendar_pattern.skeleton = decode_string(skeleton); | ||||
|         calendar_pattern.pattern = decode_string(pattern); | ||||
|         calendar_pattern.skeleton = TRY(String::from_utf8(decode_string(skeleton))); | ||||
|         calendar_pattern.pattern = TRY(String::from_utf8(decode_string(pattern))); | ||||
|         if (pattern12 != 0) | ||||
|             calendar_pattern.pattern12 = decode_string(pattern12); | ||||
|             calendar_pattern.pattern12 = TRY(String::from_utf8(decode_string(pattern12))); | ||||
| 
 | ||||
|         convert_calendar_fields(*this, calendar_pattern); | ||||
|         return calendar_pattern; | ||||
|  | @ -1808,14 +1825,14 @@ struct CalendarPatternImpl { | |||
| }; | ||||
| 
 | ||||
| struct CalendarRangePatternImpl { | ||||
|     CalendarRangePattern to_unicode_calendar_range_pattern() const { | ||||
|     ErrorOr<CalendarRangePattern> to_unicode_calendar_range_pattern() const { | ||||
|         CalendarRangePattern calendar_range_pattern {}; | ||||
| 
 | ||||
|         if (field != -1) | ||||
|             calendar_range_pattern.field = static_cast<CalendarRangePattern::Field>(field); | ||||
|         calendar_range_pattern.start_range = decode_string(start_range); | ||||
|         calendar_range_pattern.start_range = TRY(String::from_utf8(decode_string(start_range))); | ||||
|         calendar_range_pattern.separator = decode_string(separator); | ||||
|         calendar_range_pattern.end_range = decode_string(end_range); | ||||
|         calendar_range_pattern.end_range = TRY(String::from_utf8(decode_string(end_range))); | ||||
| 
 | ||||
|         convert_calendar_fields(*this, calendar_range_pattern); | ||||
|         return calendar_range_pattern; | ||||
|  | @ -1848,13 +1865,13 @@ struct CalendarRangePatternImpl { | |||
| 
 | ||||
|     generator.append(R"~~~( | ||||
| struct CalendarFormatImpl { | ||||
|     CalendarFormat to_unicode_calendar_format() const { | ||||
|     ErrorOr<CalendarFormat> to_unicode_calendar_format() const { | ||||
|         CalendarFormat calendar_format {}; | ||||
| 
 | ||||
|         calendar_format.full_format = s_calendar_patterns[full_format].to_unicode_calendar_pattern(); | ||||
|         calendar_format.long_format = s_calendar_patterns[long_format].to_unicode_calendar_pattern(); | ||||
|         calendar_format.medium_format = s_calendar_patterns[medium_format].to_unicode_calendar_pattern(); | ||||
|         calendar_format.short_format = s_calendar_patterns[short_format].to_unicode_calendar_pattern(); | ||||
|         calendar_format.full_format = TRY(s_calendar_patterns[full_format].to_unicode_calendar_pattern()); | ||||
|         calendar_format.long_format = TRY(s_calendar_patterns[long_format].to_unicode_calendar_pattern()); | ||||
|         calendar_format.medium_format = TRY(s_calendar_patterns[medium_format].to_unicode_calendar_pattern()); | ||||
|         calendar_format.short_format = TRY(s_calendar_patterns[short_format].to_unicode_calendar_pattern()); | ||||
| 
 | ||||
|         return calendar_format; | ||||
|     } | ||||
|  | @ -2110,59 +2127,59 @@ static CalendarData const* find_calendar_data(StringView locale, StringView cale | |||
|     return lookup_calendar(*default_calendar); | ||||
| } | ||||
| 
 | ||||
| Optional<CalendarFormat> get_calendar_date_format(StringView locale, StringView calendar) | ||||
| ErrorOr<Optional<CalendarFormat>> get_calendar_date_format(StringView locale, StringView calendar) | ||||
| { | ||||
|     if (auto const* data = find_calendar_data(locale, calendar); data != nullptr) { | ||||
|         auto const& formats = s_calendar_formats.at(data->date_formats); | ||||
|         return formats.to_unicode_calendar_format(); | ||||
|         return TRY(formats.to_unicode_calendar_format()); | ||||
|     } | ||||
|     return {}; | ||||
|     return OptionalNone {}; | ||||
| } | ||||
| 
 | ||||
| Optional<CalendarFormat> get_calendar_time_format(StringView locale, StringView calendar) | ||||
| ErrorOr<Optional<CalendarFormat>> get_calendar_time_format(StringView locale, StringView calendar) | ||||
| { | ||||
|     if (auto const* data = find_calendar_data(locale, calendar); data != nullptr) { | ||||
|         auto const& formats = s_calendar_formats.at(data->time_formats); | ||||
|         return formats.to_unicode_calendar_format(); | ||||
|         return TRY(formats.to_unicode_calendar_format()); | ||||
|     } | ||||
|     return {}; | ||||
|     return OptionalNone {}; | ||||
| } | ||||
| 
 | ||||
| Optional<CalendarFormat> get_calendar_date_time_format(StringView locale, StringView calendar) | ||||
| ErrorOr<Optional<CalendarFormat>> get_calendar_date_time_format(StringView locale, StringView calendar) | ||||
| { | ||||
|     if (auto const* data = find_calendar_data(locale, calendar); data != nullptr) { | ||||
|         auto const& formats = s_calendar_formats.at(data->date_time_formats); | ||||
|         return formats.to_unicode_calendar_format(); | ||||
|         return TRY(formats.to_unicode_calendar_format()); | ||||
|     } | ||||
|     return {}; | ||||
|     return OptionalNone {}; | ||||
| } | ||||
| 
 | ||||
| Vector<CalendarPattern> get_calendar_available_formats(StringView locale, StringView calendar) | ||||
| ErrorOr<Vector<CalendarPattern>> get_calendar_available_formats(StringView locale, StringView calendar) | ||||
| { | ||||
|     Vector<CalendarPattern> result {}; | ||||
| 
 | ||||
|     if (auto const* data = find_calendar_data(locale, calendar); data != nullptr) { | ||||
|         auto const& available_formats = s_calendar_pattern_lists.at(data->available_formats); | ||||
|         result.ensure_capacity(available_formats.size()); | ||||
|         TRY(result.try_ensure_capacity(available_formats.size())); | ||||
| 
 | ||||
|         for (auto const& format : available_formats) | ||||
|             result.unchecked_append(s_calendar_patterns[format].to_unicode_calendar_pattern()); | ||||
|             result.unchecked_append(TRY(s_calendar_patterns[format].to_unicode_calendar_pattern())); | ||||
|     } | ||||
| 
 | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| Optional<CalendarRangePattern> get_calendar_default_range_format(StringView locale, StringView calendar) | ||||
| ErrorOr<Optional<CalendarRangePattern>> get_calendar_default_range_format(StringView locale, StringView calendar) | ||||
| { | ||||
|     if (auto const* data = find_calendar_data(locale, calendar); data != nullptr) { | ||||
|         auto const& pattern = s_calendar_range_patterns[data->default_range_format]; | ||||
|         return pattern.to_unicode_calendar_range_pattern(); | ||||
|         return TRY(pattern.to_unicode_calendar_range_pattern()); | ||||
|     } | ||||
| 
 | ||||
|     return {}; | ||||
|     return OptionalNone {}; | ||||
| } | ||||
| 
 | ||||
| Vector<CalendarRangePattern> get_calendar_range_formats(StringView locale, StringView calendar, StringView skeleton) | ||||
| ErrorOr<Vector<CalendarRangePattern>> get_calendar_range_formats(StringView locale, StringView calendar, StringView skeleton) | ||||
| { | ||||
|     Vector<CalendarRangePattern> result {}; | ||||
| 
 | ||||
|  | @ -2173,14 +2190,14 @@ Vector<CalendarRangePattern> get_calendar_range_formats(StringView locale, Strin | |||
|             auto const& pattern = s_calendar_range_patterns[format]; | ||||
| 
 | ||||
|             if (skeleton == decode_string(pattern.skeleton)) | ||||
|                 result.append(pattern.to_unicode_calendar_range_pattern()); | ||||
|                 TRY(result.try_append(TRY(pattern.to_unicode_calendar_range_pattern()))); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| Vector<CalendarRangePattern> get_calendar_range12_formats(StringView locale, StringView calendar, StringView skeleton) | ||||
| ErrorOr<Vector<CalendarRangePattern>> get_calendar_range12_formats(StringView locale, StringView calendar, StringView skeleton) | ||||
| { | ||||
|     Vector<CalendarRangePattern> result {}; | ||||
| 
 | ||||
|  | @ -2191,7 +2208,7 @@ Vector<CalendarRangePattern> get_calendar_range12_formats(StringView locale, Str | |||
|             auto const& pattern = s_calendar_range_patterns[format]; | ||||
| 
 | ||||
|             if (skeleton == decode_string(pattern.skeleton)) | ||||
|                 result.append(pattern.to_unicode_calendar_range_pattern()); | ||||
|                 TRY(result.try_append(TRY(pattern.to_unicode_calendar_range_pattern()))); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Timothy Flynn
						Timothy Flynn