Optional ICU4C backend for segmentation.
ICU's break iterator is one to two orders of magnitude faster than the native Elixir implementation on rule-driven segmentation. This module makes it available for workloads where that matters, without making ICU a requirement for everyone else.
Enabling
The NIF is opt-in and needs:
ICU system libraries. On macOS
brew install icu4c, on Debian or Ubuntuapt install libicu-dev.The
:elixir_makedependency, which is optional and not fetched by default.The build enabled by either:
- the environment variable
UNICODE_STRING_NIF=true mix compile, or config :unicode_string, :nif, trueinconfig.exs.
- the environment variable
The config key must be in config.exs rather than runtime.exs, because it
is read at compile time to decide whether to add the :elixir_make compiler.
Using it
Pass backend: :nif to Unicode.String.split/2. When the NIF is unavailable
the native implementation is used instead, so the option is always safe:
Unicode.String.split("Hello there", break: :word, backend: :nif)available?/0 reports whether the shared library loaded.
Differences from the native implementation
The two are not always identical. ICU applies its own locale tailorings, most
visibly the CJK loose/normal/strict line break modes that the native
implementation does not have, and it uses its own dictionaries for Chinese,
Japanese, Thai, Lao, Khmer and Burmese rather than the ones this library
downloads. Where the two disagree, conformance.md describes why.
Summary
Functions
@spec available?() :: boolean()
Returns whether the ICU backend is available.
Returns
trueif the NIF shared library loaded.falseif it was not built, or if the ICU libraries are missing.
Examples
iex> is_boolean(Unicode.String.Nif.available?())
true
Splits string using the ICU break iterator.
Arguments
stringis anyString.t/0.breakis one of:grapheme,:word,:lineor:sentence.localeis an ICU locale identifier such as"en"or"ja". The default is"root".
Returns
{:ok, segments}wheresegmentsis a list ofString.t/0, or{:error, reason}, including{:error, :unavailable}when the NIF was not built.
Examples
iex> case Unicode.String.Nif.split("Hello there", :word) do
...> {:ok, segments} -> Enum.member?(segments, "Hello")
...> {:error, :unavailable} -> true
...> end
true