82 lines
2.9 KiB
Elixir
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
|