Current section
Files
Jump to
Current section
Files
lib/loader.ex
defmodule Countries.Loader do
@moduledoc false
import Countries.Utils, only: [to_map: 1]
alias Countries.Country
# loads all country data from our yaml files
# :yamerl returns a really terrible data structure
# [[{'name', 'Germany'}, {'code', 'DE'}], [{'nam:e', 'Austria'}, {'code', 'AT'}]]
# We need to transform that to maps:
# [%{name: "Germany', code: "DE"}, %{name: 'Austria', code: "AT"}]
def load do
data_path(["countries.yaml"])
|> :yamerl.decode_file()
|> List.first()
|> Enum.flat_map(fn code ->
:yamerl.decode_file(data_path(["countries", "#{code}.yaml"]))
end)
|> Enum.map(&convert_country/1)
end
defp data_path(path) do
Path.join([:code.priv_dir(:countries), "data"] ++ path)
end
defp convert_country([{_, country_data}]) do
Enum.reduce(country_data, %Country{}, fn {attribute, value}, country ->
with attribute = List.to_atom(attribute) do
Map.put(country, attribute, convert_value(attribute, value))
end
end)
end
@do_not_convert ~w[national_number_lengths national_destination_code_lengths]a
defp convert_value(_, :null),
do: nil
defp convert_value(:vat_rates, vat_rates) when not is_nil(vat_rates) do
Map.new(vat_rates, fn
{key, :null} -> {List.to_atom(key), nil}
{key, value} -> {List.to_atom(key), value}
end)
end
defp convert_value(:unofficial_names, names),
do: Enum.map(names, &to_string/1)
defp convert_value(:geo, values),
do: to_map(values)
defp convert_value(attribute, value)
when is_list(value) and not (attribute in @do_not_convert),
do: to_string(value)
defp convert_value(_, value),
do: value
end