Optional NIF interface to ICU4C for high-performance locale operations.
This module provides NIF bindings for ICU4C functions including MessageFormat 2.0 parsing and formatting, number formatting, plural rules, unit formatting and collation.
The stable way to use the NIF backend is the backend: :nif option
on the corresponding public formatting functions (for example
Localize.Number.to_string/2 and Localize.Message.format/3); the
individual functions in this module are a low-level surface whose
signatures may change with the underlying ICU API.
The NIF is opt-in and requires:
ICU system libraries installed (ICU 75+ with MF2 support).
The
elixir_makedependency.Enable the NIF via either:
- Environment variable:
LOCALIZE_NIF=true mix compile - Application config in
config.exs:config :localize, :nif, true
- Environment variable:
The config key must be set in config.exs (not runtime.exs) because
it is evaluated at compile time to include the :elixir_make compiler.
If the NIF is not available, available?/0 returns false and the
pure Elixir implementations are used automatically.
Summary
Functions
Returns whether the NIF backend is available.
Returns whether the collation NIF function is available.
Formats a MessageFormat 2 message string using ICU.
Validates a MessageFormat 2 message string using ICU's parser.
Compare two strings using ICU collation with full option support.
Formats a number using ICU4C's NumberFormatter.
Returns the plural category for a number using ICU's PluralRules.
Formats a number with a unit using ICU4C's NumberFormatter.
Functions
@spec available?() :: boolean()
Returns whether the NIF backend is available.
Returns
trueif the NIF shared library was loaded successfully.falseif the NIF is not compiled or ICU libraries are missing.
Examples
iex> is_boolean(Localize.Nif.available?())
true
@spec collation_available?() :: boolean()
Returns whether the collation NIF function is available.
Returns
trueif the collation NIF function was loaded successfully.falseif the NIF is not compiled or ICU libraries are missing.
@spec mf2_format(String.t(), String.t(), map() | String.t()) :: {:ok, String.t()} | {:error, String.t()}
Formats a MessageFormat 2 message string using ICU.
Arguments are passed as a map of %{name => value} and
encoded to JSON for the NIF.
Arguments
messageis an MF2 message string.localeis a locale identifier string. The default is"en".argsis a map of variable bindings. The default is%{}.
Returns
{:ok, formatted_string}on success.{:error, reason}on failure.
Validates a MessageFormat 2 message string using ICU's parser.
Arguments
messageis an MF2 message string.
Returns
{:ok, normalized_pattern}if the message is valid.{:error, reason}if the message is invalid.
Compare two strings using ICU collation with full option support.
This is the raw NIF function. Use Localize.Collation.compare/3
for the public interface that handles option encoding.
Arguments
string_a- the first string to compare.string_b- the second string to compare.strength- ICU strength enum value, or -1 for default.backwards- ICU backwards enum value, or -1 for default.alternate- ICU alternate enum value, or -1 for default.case_first- ICU case_first enum value, or -1 for default.case_level- ICU case_level enum value, or -1 for default.normalization- ICU normalization enum value, or -1 for default.numeric- ICU numeric enum value, or -1 for default.reorder_bin- binary of packed big-endian int32 reorder codes.
Returns
An integer: -1 (less than), 0 (equal), or 1 (greater than).
@spec number_format(number() | Decimal.t(), String.t(), Keyword.t()) :: {:ok, String.t()} | {:error, String.t()}
Formats a number using ICU4C's NumberFormatter.
This provides a reference implementation for cross-validating
the pure Elixir number formatting in Localize.Number.
Arguments
numberis a number (integer, float, or Decimal).localeis a locale identifier string (e.g.,"en-US","de").optionsis a keyword list of options.
Options
:currencyis an ISO 4217 currency code string (e.g.,"USD").:min_fraction_digitsis the minimum fractional digits.:max_fraction_digitsis the maximum fractional digits.:notationis one of"standard","scientific","compact".:use_groupingis a boolean for grouping separators.
Returns
{:ok, formatted_string}or{:error, reason}.
@spec plural_rule(number() | Decimal.t(), String.t(), :cardinal | :ordinal) :: {:ok, atom()} | {:error, String.t()}
Returns the plural category for a number using ICU's PluralRules.
Arguments
numberis a number (integer, float, or Decimal) to classify.localeis a locale identifier string (e.g.,"en","ar").typeis:cardinalor:ordinal.
Returns
{:ok, category}wherecategoryis one of:zero,:one,:two,:few,:many, or:other.{:error, reason}if ICU cannot determine the plural category.
Examples
When the NIF is available:
Localize.Nif.plural_rule(1, "en", :cardinal)
#=> {:ok, :one}
Localize.Nif.plural_rule(2, "en", :ordinal)
#=> {:ok, :two}
@spec unit_format(number() | Decimal.t(), String.t(), String.t(), Keyword.t()) :: {:ok, String.t()} | {:error, String.t()}
Formats a number with a unit using ICU4C's NumberFormatter.
Arguments
numberis a number (integer, float, or Decimal).unitis an ICU unit identifier string (e.g.,"meter","mile-per-hour").localeis a locale identifier string.optionsis a keyword list of options.
Options
:styleis"long","short", or"narrow". Default is"long".
Returns
{:ok, formatted_string}or{:error, reason}.