Packages

Pure-Elixir implementation of UTS #46 (IDNA 2008 Compatibility Processing) with Punycode (RFC 3492), bidi (RFC 5893) and CONTEXTJ joiner rules.

Current section

Files

Jump to
unicode_idna lib unicode idna mapping.ex
Raw

lib/unicode/idna/mapping.ex

defmodule Unicode.IDNA.Mapping do
@moduledoc """
UTS #46 IDNA mapping table lookup.
The mapping table classifies every Unicode code point into one of
five statuses (`:valid`, `:ignored`, `:mapped`, `:deviation` or
`:disallowed`) and, for `:mapped` and `:deviation`, supplies the
list of target code points to substitute.
This module compiles the table from `data/idna_mapping_table.txt`
at compile time and exposes a single fast-path lookup function.
"""
alias Unicode.IDNA.Utils
@typedoc "An IDNA mapping table status."
@type status :: :valid | :ignored | :mapped | :deviation | :disallowed
@typedoc """
A mapping result. The second element is `nil` for `:valid`, `:ignored`
and `:disallowed`, and a (possibly empty) list of target code points
for `:mapped` and `:deviation`.
"""
@type result :: {status, [non_neg_integer] | nil}
@doc """
Returns the IDNA mapping table status (and replacement, if any) for
a single Unicode code point.
### Arguments
* `codepoint` is a non-negative integer in the range `0..0x10FFFF`.
### Returns
* `{status, replacement}` where `status` is one of `:valid`,
`:ignored`, `:mapped`, `:deviation` or `:disallowed`, and
`replacement` is a (possibly empty) list of target code points
for `:mapped` and `:deviation`, or `nil` for the other statuses.
### Examples
iex> Unicode.IDNA.Mapping.lookup(?A)
{:mapped, [?a]}
iex> Unicode.IDNA.Mapping.lookup(?a)
{:valid, nil}
iex> Unicode.IDNA.Mapping.lookup(0x0080)
{:disallowed, nil}
iex> Unicode.IDNA.Mapping.lookup(0x00DF)
{:deviation, [?s, ?s]}
iex> Unicode.IDNA.Mapping.lookup(0x00AD)
{:ignored, nil}
"""
@spec lookup(non_neg_integer) :: result
for {first, last, status, mapping} <- Utils.idna_mapping() do
cond do
first == last ->
def lookup(unquote(first)), do: {unquote(status), unquote(mapping)}
true ->
def lookup(codepoint) when codepoint in unquote(first)..unquote(last),
do: {unquote(status), unquote(mapping)}
end
end
end