Current section
Files
Jump to
Current section
Files
lib/postal_code.ex
defmodule PostalCode do
@moduledoc """
Postal code parser for the Norwegian postal code system.
"""
@doc """
Accepts a postal code in string format, and returns the postal place.
## Examples
iex> PostalCode.postal_code_to_place("0186")
{:ok, "OSLO"}
iex> PostalCode.postal_code_to_place("0638")
:no_results
iex> PostalCode.postal_code_to_place(0186)
{:error, "Invalid type of postal code, must be string."}
iex> PostalCode.postal_code_to_place("018")
{:error, "Length must be 4."}
"""
def postal_code_to_place(postal_code) when is_binary(postal_code) and bit_size(postal_code) == 32 do
case get_matching_postal_code(postal_code) do
[_postal_code, place, _county_code, _county_name, _category] ->
{:ok, place}
nil ->
:no_results
end
end
def postal_code_to_place(postal_code) when is_binary(postal_code), do: {:error, "Length must be 4."}
def postal_code_to_place(_postal_code), do: {:error, "Invalid type of postal code, must be string."}
@doc false
defp get_postal_codes do
Path.join(File.cwd!(), "postal_codes.csv")
|> Path.expand(__DIR__)
|> File.read!()
|> String.split("\n")
|> Enum.map(fn x -> x |> String.replace("\r", "") |> String.split("\t") end)
end
@doc false
defp get_matching_postal_code(postal_code) do
Enum.find(get_postal_codes(), fn x -> Enum.at(x, 0) == postal_code end)
end
end