Packages
ex_cldr
2.47.1
2.47.5
2.47.4
2.47.3
2.47.2
2.47.1
2.47.0
2.46.0
2.45.2
2.45.1
2.45.0
2.44.1
2.44.0
2.43.2
2.43.1
2.43.0
2.42.0
2.41.1
2.41.0
2.40.4
2.40.3
2.40.2
2.40.1
2.40.0
2.39.2
2.39.1
2.39.0
2.38.1
2.38.0
2.37.5
2.37.4
2.37.3
retired
2.37.2
2.37.1
2.37.0
2.36.0
2.35.1
2.35.0
retired
2.34.2
2.34.1
2.34.0
2.33.2
2.33.1
2.33.1-rc.0
2.33.0
2.32.1
2.32.0
2.31.0
2.30.0
2.29.0
2.28.0
2.27.1
2.27.0
retired
2.26.3
2.26.2
2.26.1
2.26.0
2.25.0
2.24.2
2.24.1
2.24.0
2.24.0-rc.6
2.24.0-rc.5
2.24.0-rc.4
2.24.0-rc.3
2.24.0-rc.2
2.24.0-rc.1
2.24.0-rc.0
2.23.2
2.23.1
2.23.0
2.22.1
2.22.0
2.21.0
2.20.0
2.20.0-rc.3
2.20.0-rc.2
2.20.0-rc.1
2.20.0-rc.0
2.19.1
2.19.0
2.18.2
2.18.1
2.18.0
2.18.0-rc.0
2.17.2
2.17.1
2.17.0
2.16.2
2.16.1
2.16.1-rc.0
2.16.0
2.15.0
2.14.1
2.14.0
2.14.0-rc.0
2.13.0
2.12.1
2.12.0
2.11.1
2.11.0
2.10.2
2.10.1
2.10.0
retired
2.9.0
2.8.1
2.8.0
2.7.2
2.7.1
2.7.0
2.6.2
2.6.1
2.6.0
2.5.0
2.4.3
2.4.2
2.4.1
2.4.0
2.3.2
2.3.1
2.3.0
2.2.7
2.2.6
2.2.5
2.2.4
2.2.3
2.2.2
2.2.1
2.2.0
2.1.0
2.0.4
2.0.3
2.0.2
2.0.1
2.0.0
2.0.0-rc.3
retired
2.0.0-rc.2
retired
2.0.0-rc.1
retired
2.0.0-rc.0
retired
1.8.2
1.8.1
1.8.0
1.7.1
1.7.0
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.5.2
1.5.1
1.5.0
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
retired
1.4.0-rc.3
retired
1.4.0-rc.2
retired
1.4.0-rc.1
retired
1.4.0-rc.0
retired
1.3.2
1.3.1
1.3.0
1.2.0
1.1.0
1.0.0
1.0.0-rc.3
retired
1.0.0-rc.2
retired
1.0.0-rc.1
retired
1.0.0-rc.0
retired
0.13.1
0.13.0
0.12.2
retired
0.12.1
retired
0.12.0
retired
0.11.0
retired
0.10.0
retired
0.9.0
retired
0.8.3
retired
0.8.2
retired
0.8.1
retired
0.8.0
retired
0.7.0
retired
0.6.2
retired
0.6.1
retired
0.6.0
retired
0.5.2
retired
0.5.1
retired
0.5.0
retired
0.4.2
retired
0.4.1
retired
0.4.0
retired
0.3.0
retired
0.2.1
retired
0.2.0
retired
0.1.3
retired
0.1.2
retired
0.1.1
retired
0.1.0
retired
0.0.20
retired
0.0.19
retired
0.0.18
retired
0.0.17
retired
0.0.16
retired
0.0.15
retired
0.0.14
retired
0.0.13
retired
0.0.12
retired
0.0.11
retired
0.0.10
retired
0.0.8
retired
0.0.7
retired
0.0.6
retired
0.0.5
retired
0.0.4
retired
0.0.3
retired
Common Locale Data Repository (CLDR) functions for Elixir to localize and format numbers, dates, lists, messages, languages, territories and units with support for over 700 locales for internationalized (i18n) and localized (L10N) applications.
Current section
Files
Jump to
Current section
Files
lib/cldr/validity.ex
defmodule Cldr.Validity do
@moduledoc false
@doc """
Normalizes a language tag field.
"""
@callback normalize(String.t() | atom()) :: String.t() | atom()
@doc """
Validates a language tag field
"""
@callback validate(String.t() | atom()) :: {:ok, term, atom()} | {:error, String.t()}
defmacro __using__(type) do
validity_data = Cldr.Config.validity(type)
Cldr.Validity.generate_validity_checks(validity_data)
end
@doc false
def generate_validity_checks(validity_data) do
quote bind_quoted: [validity_data: Macro.escape(validity_data)] do
for {status, codes} <- validity_data do
{code_ranges, simple_codes} = Cldr.Validity.partition(codes)
simple_check =
if length(simple_codes) > 0 do
defp valid(code) when code in unquote(simple_codes) do
{:ok, code, unquote(status)}
end
end
range_check =
for range <- code_ranges, range != [] do
{base, range_start, range_end} = Cldr.Validity.range_from(range)
defp valid(unquote(base) <> <<char::utf8>> = code)
when char in unquote(range_start)..unquote(range_end) do
{:ok, code, unquote(status)}
end
end
end
defp valid(code) do
{:error, code}
end
end
end
@doc false
def partition(list) do
Enum.reduce(list, {[], []}, fn elem, {ranges, simple} ->
if String.contains?(elem, "~") do
{[elem | ranges], simple}
else
{ranges, [elem | simple]}
end
end)
end
@doc false
def range_from(code_range) do
[left, range_end] = String.split(code_range, "~")
{base, range_start} = String.split_at(left, -1)
<<range_start::utf8>> = range_start
<<range_end::utf8>> = range_end
{base, range_start, range_end}
end
# Only used for testing
@doc false
def all_valid(type) do
validity_data = Cldr.Config.validity(type)
for {_status, codes} <- validity_data do
{code_ranges, simple_codes} = partition(codes)
range_check =
for range <- code_ranges, range != [] do
{base, range_start, range_end} = range_from(range)
for char <- range_start..range_end do
base <> <<char::utf8>>
end
end
simple_codes ++ range_check
end
|> List.flatten()
end
# Returns a list of known data that omits
# valid (per the spec) but shouldn't be used
# in general practise
@omit_status [:deprecated, :reserved, :special, :unknown, :private_use]
@doc false
def known(type) do
validity_data = Cldr.Config.validity(type)
for {status, codes} <- validity_data, status not in @omit_status do
{code_ranges, simple_codes} = partition(codes)
range_check =
for range <- code_ranges, range != [] do
{base, range_start, range_end} = range_from(range)
for char <- range_start..range_end do
base <> <<char::utf8>>
end
end
simple_codes ++ range_check
end
|> List.flatten()
end
end