api-v2/deps/tzdata/lib/tzdata/parser_organizer.ex
2025-04-16 10:03:13 -03:00

82 lines
2.9 KiB
Elixir

defmodule Tzdata.ParserOrganizer do
@moduledoc false
# List of zone names. Canonical zones only. No links.
def zone_list(from_initial_pass) do
from_initial_pass
|>Enum.filter(fn elem -> elem.record_type == :zone end)
|>Enum.map(fn elem -> elem.name end)
|>Enum.sort
end
# List of link names.
def link_list(from_initial_pass) do
from_initial_pass
|>Enum.filter(fn elem -> elem.record_type == :link end)
|>Enum.map(fn elem -> elem.to end)
|>Enum.sort
end
# Combined list of zone- and link-names
def zone_and_link_list(from_initial_pass) do
zone_list(from_initial_pass) ++ link_list(from_initial_pass)
|> Enum.sort
end
def links(from_initial_pass) do
link_records = filter_for_record_type(from_initial_pass, :link)
add_links_to_map(%{}, link_records)
end
defp add_links_to_map(map, []), do: map
defp add_links_to_map(map, [head|tail]) do
map = Map.put(map, head.to, head.from)
add_links_to_map(map, tail)
end
def zones(from_initial_pass), do: map_with_name_key(from_initial_pass, :zone)
def rules(from_initial_pass) do
map = empty_rules_map(from_initial_pass)
rules = filter_for_record_type(from_initial_pass, :rule)
add_rules_to_map(map, rules)
end
defp add_rules_to_map(map, []), do: map
defp add_rules_to_map(map, [rule|tail]) do
# add rule to rule list
new_rule_list = map[rule.name] ++ [rule]
# update map with new rule list for rule name
map = Map.put(map, rule.name, new_rule_list)
add_rules_to_map(map, tail)
end
# Returns map with keys for all the rules and empty lists as values
defp empty_rules_map(from_initial_pass) do
from_initial_pass
|> filter_for_record_type(:rule)
|> list_of_single_value_from_map_list(:name)
|> Enum.uniq # at this point we have a list of unique Rule names
|> Enum.map(fn elem -> Map.put(%{}, elem, []) end)
# after merging we have a map with Rule names as keys and empty list as vals
|> merge_maps_in_list
end
defp list_of_single_value_from_map_list(list, key), do: Enum.map(list, fn elem -> elem[key] end)
defp filter_for_record_type(list, record_type), do: Enum.filter(list, fn x -> (x.record_type == record_type) end)
# Takes a list of maps. Returns map with keys that are :name of
# the map, and values being the map
def map_with_name_key(from_initial_pass, record_type) do
from_initial_pass
|> Enum.filter(fn x -> (x.record_type == record_type) end)
# Build list of maps with zone name as key
|> Enum.map(fn x -> Map.put(%{}, x.name, x) end)
# Merge all the maps together to one map with all the zones
|> merge_maps_in_list
end
# takes a list of maps and merges them all together
def merge_maps_in_list(list), do: merge_maps_in_list(list, %{})
defp merge_maps_in_list([], map), do: map
defp merge_maps_in_list([head|tail], map) do
merge_maps_in_list(tail, Map.merge(head, map))
end
end