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. Additional functions for number, date/time, and unit formatting will be added as the library grows.
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.Nif.nif_compare/3
for the higher-level 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}.