From 0ff3f8c5eb3d2af842b1bb160c62684a5c439074 Mon Sep 17 00:00:00 2001 From: Sebastian Szturo Date: Mon, 2 Feb 2015 22:53:51 +0900 Subject: [PATCH] :rocket: Load country data on compile time --- lib/countries.ex | 61 +++++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/lib/countries.ex b/lib/countries.ex index 7fe123c..b7605ad 100644 --- a/lib/countries.ex +++ b/lib/countries.ex @@ -22,32 +22,41 @@ defmodule Countries do country[attribute] == value_as_char_list end) end - - defp countries do - # Lets load all country data from our yaml files - codes = List.first(:yamerl.decode_file(data_path "countries.yaml")) - country_data = - Enum.reduce(codes, [], fn (code, countries) -> - countries ++ :yamerl.decode_file(data_path "countries/#{code}.yaml") - end) - - # :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"}] - countries = - Enum.reduce(country_data, [], fn (country_data, countries) -> - country = - Enum.reduce(country_data, %Country{}, fn({key, value}, country) -> - key_as_atom = String.to_atom(to_string key) - Map.put(country, key_as_atom, value) - end) - - List.insert_at(countries, 0, country) - end) - end - - defp data_path(path) do + + #-- Load countries from yaml files once on compile time --- + + # Ensure :yamerl is running + Application.ensure_all_started(:yamerl) + + data_path = fn(path) -> Path.join("data", path) |> Path.expand(__DIR__) end + + # Lets load all country data from our yaml files + codes = List.first(:yamerl.decode_file data_path.("/countries.yaml")) + country_data = + Enum.reduce(codes, [], fn (code, countries) -> + countries ++ :yamerl.decode_file data_path.("countries/#{code}.yaml") + end) + + # :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"}] + countries = + Enum.reduce(country_data, [], fn (country_data, countries) -> + country = + Enum.reduce(country_data, %Country{}, fn({attribute, value}, country) -> + attribute_as_atom = String.to_atom(to_string attribute) + Map.put(country, attribute_as_atom, value) + end) + + List.insert_at(countries, 0, country) + end) + + defp countries do + # Maps and Structs need to be escaped before unquoting + unquote Macro.escape(countries) + end + end