From 0bc401a1d653f487738e05e8677dfe5167fc5a36 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Tue, 3 Oct 2023 12:02:53 -0400 Subject: [PATCH] LibTimeZone+Userland: Include Link entries when returning all time zones We currently only return primary time zones, i.e. time zones that are not a Link. LibJS will require knowledge of Link entries, and whether each entry is or is not a Link. --- .../LibTimeZone/GenerateTimeZoneData.cpp | 38 ++++++++++++++++++- .../ClockSettings/TimeZoneSettingsWidget.cpp | 12 +++++- .../Libraries/LibJS/Runtime/Intl/Intl.cpp | 4 +- Userland/Libraries/LibTimeZone/TimeZone.cpp | 4 +- Userland/Libraries/LibTimeZone/TimeZone.h | 12 +++++- Userland/Utilities/timezone.cpp | 2 +- 6 files changed, 63 insertions(+), 9 deletions(-) diff --git a/Meta/Lagom/Tools/CodeGenerators/LibTimeZone/GenerateTimeZoneData.cpp b/Meta/Lagom/Tools/CodeGenerators/LibTimeZone/GenerateTimeZoneData.cpp index 0d5e8cb91f..091c029547 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibTimeZone/GenerateTimeZoneData.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibTimeZone/GenerateTimeZoneData.cpp @@ -67,6 +67,8 @@ struct TimeZoneData { HashMap> time_zone_regions; Vector time_zone_region_names; + + Vector time_zones_and_links; }; } @@ -127,6 +129,17 @@ struct AK::Formatter : Formatter { } }; +template<> +struct AK::Formatter : Formatter { + ErrorOr format(FormatBuilder& builder, TimeZone::TimeZoneIdentifier const& time_zone) + { + return Formatter::format(builder, + "{{ \"{}\"sv, IsLink::{} }}"sv, + time_zone.name, + time_zone.is_link == TimeZone::IsLink::Yes ? "Yes"sv : "No"sv); + } +}; + template<> struct AK::Formatter : Formatter { ErrorOr format(FormatBuilder& builder, TimeZone::Coordinate const& coordinate) @@ -249,8 +262,10 @@ static Vector& parse_zone(StringView zone_line, TimeZoneData& ti auto& time_zones = time_zone_data.time_zones.ensure(name); time_zones.append(move(time_zone)); - if (!time_zone_data.time_zone_names.contains_slow(name)) + if (!time_zone_data.time_zone_names.contains_slow(name)) { time_zone_data.time_zone_names.append(name); + time_zone_data.time_zones_and_links.append({ time_zone_data.time_zone_names.last(), TimeZone::IsLink::No }); + } return time_zones; } @@ -281,6 +296,7 @@ static void parse_link(StringView link_line, TimeZoneData& time_zone_data) auto alias = segments[2]; time_zone_data.time_zone_aliases.append({ target, alias }); + time_zone_data.time_zones_and_links.append({ time_zone_data.time_zone_aliases.last().alias, TimeZone::IsLink::Yes }); } static void parse_rule(StringView rule_line, TimeZoneData& time_zone_data) @@ -794,9 +810,27 @@ Vector time_zones_in_region(StringView region) } )~~~"); - generate_available_values(generator, "all_time_zones"sv, time_zone_data.time_zone_names); + quick_sort(time_zone_data.time_zones_and_links, [](auto const& lhs, auto const& rhs) { + return lhs.name < rhs.name; + }); + + generator.set("time_zones_and_links_size", MUST(String::number(time_zone_data.time_zones_and_links.size()))); generator.append(R"~~~( +ReadonlySpan all_time_zones() +{ + static constexpr Array time_zones_and_links { {)~~~"); + + bool first = true; + for (auto const& zone : time_zone_data.time_zones_and_links) { + generator.append(first ? " "sv : ", "sv); + generator.append(MUST(String::formatted("{}", zone))); + first = false; + } + generator.append(R"~~~( } }; + + return time_zones_and_links.span(); +} } )~~~"); diff --git a/Userland/Applications/ClockSettings/TimeZoneSettingsWidget.cpp b/Userland/Applications/ClockSettings/TimeZoneSettingsWidget.cpp index 4cffade8c3..06a5ebad55 100644 --- a/Userland/Applications/ClockSettings/TimeZoneSettingsWidget.cpp +++ b/Userland/Applications/ClockSettings/TimeZoneSettingsWidget.cpp @@ -63,7 +63,17 @@ TimeZoneSettingsWidget::TimeZoneSettingsWidget() { load_from_gml(time_zone_settings_widget_gml).release_value_but_fixme_should_propagate_errors(); - static auto time_zones = TimeZone::all_time_zones(); + static auto time_zones = []() { + Vector time_zones; + + for (auto const& time_zone : TimeZone::all_time_zones()) { + if (time_zone.is_link == TimeZone::IsLink::No) + time_zones.append(time_zone.name); + } + + return time_zones; + }(); + m_time_zone = TimeZone::system_time_zone(); m_time_zone_combo_box = *find_descendant_of_type_named("time_zone_input"); diff --git a/Userland/Libraries/LibJS/Runtime/Intl/Intl.cpp b/Userland/Libraries/LibJS/Runtime/Intl/Intl.cpp index 1911ac314d..3204030827 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/Intl.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/Intl.cpp @@ -87,10 +87,10 @@ static Vector available_canonical_time_zones() Vector result; // 3. For each element name of names, do - for (auto name : names) { + for (auto const& name : names) { // a. Assert: IsValidTimeZoneName( name ) is true. // b. Let canonical be ! CanonicalizeTimeZoneName( name ). - auto canonical = TimeZone::canonicalize_time_zone(name).value(); + auto canonical = TimeZone::canonicalize_time_zone(name.name).value(); // c. If result does not contain an element equal to canonical, then if (!result.contains_slow(canonical)) { diff --git a/Userland/Libraries/LibTimeZone/TimeZone.cpp b/Userland/Libraries/LibTimeZone/TimeZone.cpp index b986803d64..84959efecb 100644 --- a/Userland/Libraries/LibTimeZone/TimeZone.cpp +++ b/Userland/Libraries/LibTimeZone/TimeZone.cpp @@ -143,10 +143,10 @@ ErrorOr change_time_zone([[maybe_unused]] StringView time_zone) #endif } -ReadonlySpan __attribute__((weak)) all_time_zones() +ReadonlySpan __attribute__((weak)) all_time_zones() { #if !ENABLE_TIME_ZONE_DATA - static constexpr auto utc = Array { "UTC"sv }; + static constexpr auto utc = Array { TimeZoneIdentifier { "UTC"sv, IsLink::No } }; return utc; #else return {}; diff --git a/Userland/Libraries/LibTimeZone/TimeZone.h b/Userland/Libraries/LibTimeZone/TimeZone.h index 23ba3103d1..5f1b18ef80 100644 --- a/Userland/Libraries/LibTimeZone/TimeZone.h +++ b/Userland/Libraries/LibTimeZone/TimeZone.h @@ -19,6 +19,16 @@ namespace TimeZone { +enum class IsLink { + No, + Yes, +}; + +struct TimeZoneIdentifier { + StringView name; + IsLink is_link { IsLink::No }; +}; + enum class InDST { No, Yes, @@ -52,7 +62,7 @@ struct Location { StringView system_time_zone(); StringView current_time_zone(); ErrorOr change_time_zone(StringView time_zone); -ReadonlySpan all_time_zones(); +ReadonlySpan all_time_zones(); Optional time_zone_from_string(StringView time_zone); StringView time_zone_to_string(TimeZone time_zone); diff --git a/Userland/Utilities/timezone.cpp b/Userland/Utilities/timezone.cpp index 44d45077fc..3cab696807 100644 --- a/Userland/Utilities/timezone.cpp +++ b/Userland/Utilities/timezone.cpp @@ -27,7 +27,7 @@ ErrorOr serenity_main(Main::Arguments arguments) if (list_time_zones) { for (auto time_zone : TimeZone::all_time_zones()) - outln("{}", time_zone); + outln("{}", time_zone.name); return 0; }