Packages

Translation, spelling and direction of locales

Current section

Files

Jump to
locale_names lib locale_builder.ex
Raw

lib/locale_builder.ex

defmodule LocaleBuilder do
@moduledoc false
@spec all_locale_codes() :: list(Locale.locale_code())
def all_locale_codes do
CLDR.available_locales()
|> Enum.reduce([], fn locale, acc ->
if String.contains?(locale, "-") do
[locale | acc]
else
[locale <> "-" <> String.upcase(locale) | [locale | acc]]
end
end)
end
@spec english_locale_name(Locale.locale_code()) ::
{:ok, String.t()} | {:error, :locale_not_found}
def english_locale_name(locale_code) do
display_names =
"en"
|> language_from_locale_code()
|> CLDR.get_display_names()
case display_names do
{:error, :locale_not_found} -> display_names
name_map -> {:ok, display_name(name_map, locale_code)}
end
end
@spec locale?(Locale.locale_code()) :: boolean()
def locale?(locale_code) do
Enum.member?(all_locale_codes(), locale_code)
end
@spec locale(Locale.locale_code()) :: {:ok, Locale.locale()} | {:error, String.t()}
def locale(locale_code) do
with {:ok, direction} <- locale_direction(locale_code),
{:ok, name} <- locale_name(locale_code),
{:ok, english_name} <- english_locale_name(locale_code) do
{:ok,
%Locale{
english_name: english_name,
direction: direction,
locale_code: locale_code,
name: name
}}
else
error -> error
end
end
@spec locale_direction(Locale.locale_code()) ::
{:ok, Locale.direction_type()} | {:error, :locale_not_found}
def locale_direction(locale_code) do
with language = language_from_locale_code(locale_code),
{:ok, script} <- CLDR.likely_script(language, locale_code),
direction <- CLDR.direction_from_script(script) do
{:ok, direction}
else
_error -> {:error, :locale_not_found}
end
end
@spec locale_name(Locale.locale_code()) :: {:ok, String.t()} | {:error, :locale_not_found}
def locale_name(locale_code) do
display_names =
locale_code
|> language_from_locale_code()
|> CLDR.get_display_names()
case display_names do
{:error, :locale_not_found} = error -> error
name_map -> {:ok, display_name(name_map, locale_code)}
end
end
@spec capitalize(String.t()) :: String.t() | nil
defp capitalize(nil), do: nil
defp capitalize(string) do
{first, rest} = String.split_at(string, 1)
String.upcase(first) <> rest
end
@spec display_name(%{}, Locale.locale_code()) :: String.t() | :language_not_found
defp display_name(display_names, locale_code) do
language = language_from_locale_code(locale_code)
case Map.Extra.fetch_first(display_names, [locale_code, language], :language_not_found) do
{:error, :language_not_found} -> :language_not_found
{:ok, name} -> capitalize(name)
end
end
@spec language_from_locale_code(Locale.locale_code()) :: CLDR.language() | nil
defp language_from_locale_code(locale_code) do
locale_code
|> String.split("-")
|> Enum.at(0)
end
end